Index: vendor/libc++/dist/include/__tree =================================================================== --- vendor/libc++/dist/include/__tree (revision 304764) +++ vendor/libc++/dist/include/__tree (revision 304765) @@ -1,2643 +1,2647 @@ // -*- C++ -*- //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP___TREE #define _LIBCPP___TREE #include <__config> #include #include #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD template class __tree; template class _LIBCPP_TYPE_VIS_ONLY __tree_iterator; template class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; template class __tree_end_node; template class __tree_node_base; template class __tree_node; #ifndef _LIBCPP_CXX03_LANG template union __value_type; #else template struct __value_type; #endif template class __map_node_destructor; template class _LIBCPP_TYPE_VIS_ONLY __map_iterator; template class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; /* _NodePtr algorithms The algorithms taking _NodePtr are red black tree algorithms. Those algorithms taking a parameter named __root should assume that __root points to a proper red black tree (unless otherwise specified). Each algorithm herein assumes that __root->__parent_ points to a non-null structure which has a member __left_ which points back to __root. No other member is read or written to at __root->__parent_. __root->__parent_ will be referred to below (in comments only) as end_node. end_node->__left_ is an externably accessible lvalue for __root, and can be changed by node insertion and removal (without explicit reference to end_node). All nodes (with the exception of end_node), even the node referred to as __root, have a non-null __parent_ field. */ // Returns: true if __x is a left child of its parent, else false // Precondition: __x != nullptr. template inline _LIBCPP_INLINE_VISIBILITY bool __tree_is_left_child(_NodePtr __x) _NOEXCEPT { return __x == __x->__parent_->__left_; } // Determintes if the subtree rooted at __x is a proper red black subtree. If // __x is a proper subtree, returns the black height (null counts as 1). If // __x is an improper subtree, returns 0. template unsigned __tree_sub_invariant(_NodePtr __x) { if (__x == nullptr) return 1; // parent consistency checked by caller // check __x->__left_ consistency if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x) return 0; // check __x->__right_ consistency if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x) return 0; // check __x->__left_ != __x->__right_ unless both are nullptr if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr) return 0; // If this is red, neither child can be red if (!__x->__is_black_) { if (__x->__left_ && !__x->__left_->__is_black_) return 0; if (__x->__right_ && !__x->__right_->__is_black_) return 0; } unsigned __h = __tree_sub_invariant(__x->__left_); if (__h == 0) return 0; // invalid left subtree if (__h != __tree_sub_invariant(__x->__right_)) return 0; // invalid or different height right subtree return __h + __x->__is_black_; // return black height of this node } // Determintes if the red black tree rooted at __root is a proper red black tree. // __root == nullptr is a proper tree. Returns true is __root is a proper // red black tree, else returns false. template bool __tree_invariant(_NodePtr __root) { if (__root == nullptr) return true; // check __x->__parent_ consistency if (__root->__parent_ == nullptr) return false; if (!__tree_is_left_child(__root)) return false; // root must be black if (!__root->__is_black_) return false; // do normal node checks return __tree_sub_invariant(__root) != 0; } // Returns: pointer to the left-most node under __x. // Precondition: __x != nullptr. template inline _LIBCPP_INLINE_VISIBILITY _NodePtr __tree_min(_NodePtr __x) _NOEXCEPT { while (__x->__left_ != nullptr) __x = __x->__left_; return __x; } // Returns: pointer to the right-most node under __x. // Precondition: __x != nullptr. template inline _LIBCPP_INLINE_VISIBILITY _NodePtr __tree_max(_NodePtr __x) _NOEXCEPT { while (__x->__right_ != nullptr) __x = __x->__right_; return __x; } // Returns: pointer to the next in-order node after __x. // Precondition: __x != nullptr. template _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT { if (__x->__right_ != nullptr) return __tree_min(__x->__right_); while (!__tree_is_left_child(__x)) __x = __x->__parent_unsafe(); return __x->__parent_unsafe(); } template inline _LIBCPP_INLINE_VISIBILITY _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT { if (__x->__right_ != nullptr) return static_cast<_EndNodePtr>(__tree_min(__x->__right_)); while (!__tree_is_left_child(__x)) __x = __x->__parent_unsafe(); return static_cast<_EndNodePtr>(__x->__parent_); } // Returns: pointer to the previous in-order node before __x. // Precondition: __x != nullptr. // Note: __x may be the end node. template inline _LIBCPP_INLINE_VISIBILITY _NodePtr __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT { if (__x->__left_ != nullptr) return __tree_max(__x->__left_); _NodePtr __xx = static_cast<_NodePtr>(__x); while (__tree_is_left_child(__xx)) __xx = __xx->__parent_unsafe(); return __xx->__parent_unsafe(); } // Returns: pointer to a node which has no children // Precondition: __x != nullptr. template _NodePtr __tree_leaf(_NodePtr __x) _NOEXCEPT { while (true) { if (__x->__left_ != nullptr) { __x = __x->__left_; continue; } if (__x->__right_ != nullptr) { __x = __x->__right_; continue; } break; } return __x; } // Effects: Makes __x->__right_ the subtree root with __x as its left child // while preserving in-order order. // Precondition: __x->__right_ != nullptr template void __tree_left_rotate(_NodePtr __x) _NOEXCEPT { _NodePtr __y = __x->__right_; __x->__right_ = __y->__left_; if (__x->__right_ != nullptr) __x->__right_->__set_parent(__x); __y->__parent_ = __x->__parent_; if (__tree_is_left_child(__x)) __x->__parent_->__left_ = __y; else __x->__parent_unsafe()->__right_ = __y; __y->__left_ = __x; __x->__set_parent(__y); } // Effects: Makes __x->__left_ the subtree root with __x as its right child // while preserving in-order order. // Precondition: __x->__left_ != nullptr template void __tree_right_rotate(_NodePtr __x) _NOEXCEPT { _NodePtr __y = __x->__left_; __x->__left_ = __y->__right_; if (__x->__left_ != nullptr) __x->__left_->__set_parent(__x); __y->__parent_ = __x->__parent_; if (__tree_is_left_child(__x)) __x->__parent_->__left_ = __y; else __x->__parent_unsafe()->__right_ = __y; __y->__right_ = __x; __x->__set_parent(__y); } // Effects: Rebalances __root after attaching __x to a leaf. // Precondition: __root != nulptr && __x != nullptr. // __x has no children. // __x == __root or == a direct or indirect child of __root. // If __x were to be unlinked from __root (setting __root to // nullptr if __root == __x), __tree_invariant(__root) == true. // Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_ // may be different than the value passed in as __root. template void __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { __x->__is_black_ = __x == __root; while (__x != __root && !__x->__parent_unsafe()->__is_black_) { // __x->__parent_ != __root because __x->__parent_->__is_black == false if (__tree_is_left_child(__x->__parent_unsafe())) { _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; if (__y != nullptr && !__y->__is_black_) { __x = __x->__parent_unsafe(); __x->__is_black_ = true; __x = __x->__parent_unsafe(); __x->__is_black_ = __x == __root; __y->__is_black_ = true; } else { if (!__tree_is_left_child(__x)) { __x = __x->__parent_unsafe(); __tree_left_rotate(__x); } __x = __x->__parent_unsafe(); __x->__is_black_ = true; __x = __x->__parent_unsafe(); __x->__is_black_ = false; __tree_right_rotate(__x); break; } } else { _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; if (__y != nullptr && !__y->__is_black_) { __x = __x->__parent_unsafe(); __x->__is_black_ = true; __x = __x->__parent_unsafe(); __x->__is_black_ = __x == __root; __y->__is_black_ = true; } else { if (__tree_is_left_child(__x)) { __x = __x->__parent_unsafe(); __tree_right_rotate(__x); } __x = __x->__parent_unsafe(); __x->__is_black_ = true; __x = __x->__parent_unsafe(); __x->__is_black_ = false; __tree_left_rotate(__x); break; } } } } // Precondition: __root != nullptr && __z != nullptr. // __tree_invariant(__root) == true. // __z == __root or == a direct or indirect child of __root. // Effects: unlinks __z from the tree rooted at __root, rebalancing as needed. // Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_ // nor any of its children refer to __z. end_node->__left_ // may be different than the value passed in as __root. template void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT { // __z will be removed from the tree. Client still needs to destruct/deallocate it // __y is either __z, or if __z has two children, __tree_next(__z). // __y will have at most one child. // __y will be the initial hole in the tree (make the hole at a leaf) _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ? __z : __tree_next(__z); // __x is __y's possibly null single child _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_; // __w is __x's possibly null uncle (will become __x's sibling) _NodePtr __w = nullptr; // link __x to __y's parent, and find __w if (__x != nullptr) __x->__parent_ = __y->__parent_; if (__tree_is_left_child(__y)) { __y->__parent_->__left_ = __x; if (__y != __root) __w = __y->__parent_unsafe()->__right_; else __root = __x; // __w == nullptr } else { __y->__parent_unsafe()->__right_ = __x; // __y can't be root if it is a right child __w = __y->__parent_->__left_; } bool __removed_black = __y->__is_black_; // If we didn't remove __z, do so now by splicing in __y for __z, // but copy __z's color. This does not impact __x or __w. if (__y != __z) { // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr __y->__parent_ = __z->__parent_; if (__tree_is_left_child(__z)) __y->__parent_->__left_ = __y; else __y->__parent_unsafe()->__right_ = __y; __y->__left_ = __z->__left_; __y->__left_->__set_parent(__y); __y->__right_ = __z->__right_; if (__y->__right_ != nullptr) __y->__right_->__set_parent(__y); __y->__is_black_ = __z->__is_black_; if (__root == __z) __root = __y; } // There is no need to rebalance if we removed a red, or if we removed // the last node. if (__removed_black && __root != nullptr) { // Rebalance: // __x has an implicit black color (transferred from the removed __y) // associated with it, no matter what its color is. // If __x is __root (in which case it can't be null), it is supposed // to be black anyway, and if it is doubly black, then the double // can just be ignored. // If __x is red (in which case it can't be null), then it can absorb // the implicit black just by setting its color to black. // Since __y was black and only had one child (which __x points to), __x // is either red with no children, else null, otherwise __y would have // different black heights under left and right pointers. // if (__x == __root || __x != nullptr && !__x->__is_black_) if (__x != nullptr) __x->__is_black_ = true; else { // Else __x isn't root, and is "doubly black", even though it may // be null. __w can not be null here, else the parent would // see a black height >= 2 on the __x side and a black height // of 1 on the __w side (__w must be a non-null black or a red // with a non-null black child). while (true) { if (!__tree_is_left_child(__w)) // if x is left child { if (!__w->__is_black_) { __w->__is_black_ = true; __w->__parent_unsafe()->__is_black_ = false; __tree_left_rotate(__w->__parent_unsafe()); // __x is still valid // reset __root only if necessary if (__root == __w->__left_) __root = __w; // reset sibling, and it still can't be null __w = __w->__left_->__right_; } // __w->__is_black_ is now true, __w may have null children if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && (__w->__right_ == nullptr || __w->__right_->__is_black_)) { __w->__is_black_ = false; __x = __w->__parent_unsafe(); // __x can no longer be null if (__x == __root || !__x->__is_black_) { __x->__is_black_ = true; break; } // reset sibling, and it still can't be null __w = __tree_is_left_child(__x) ? __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; // continue; } else // __w has a red child { if (__w->__right_ == nullptr || __w->__right_->__is_black_) { // __w left child is non-null and red __w->__left_->__is_black_ = true; __w->__is_black_ = false; __tree_right_rotate(__w); // __w is known not to be root, so root hasn't changed // reset sibling, and it still can't be null __w = __w->__parent_unsafe(); } // __w has a right red child, left child may be null __w->__is_black_ = __w->__parent_unsafe()->__is_black_; __w->__parent_unsafe()->__is_black_ = true; __w->__right_->__is_black_ = true; __tree_left_rotate(__w->__parent_unsafe()); break; } } else { if (!__w->__is_black_) { __w->__is_black_ = true; __w->__parent_unsafe()->__is_black_ = false; __tree_right_rotate(__w->__parent_unsafe()); // __x is still valid // reset __root only if necessary if (__root == __w->__right_) __root = __w; // reset sibling, and it still can't be null __w = __w->__right_->__left_; } // __w->__is_black_ is now true, __w may have null children if ((__w->__left_ == nullptr || __w->__left_->__is_black_) && (__w->__right_ == nullptr || __w->__right_->__is_black_)) { __w->__is_black_ = false; __x = __w->__parent_unsafe(); // __x can no longer be null if (!__x->__is_black_ || __x == __root) { __x->__is_black_ = true; break; } // reset sibling, and it still can't be null __w = __tree_is_left_child(__x) ? __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; // continue; } else // __w has a red child { if (__w->__left_ == nullptr || __w->__left_->__is_black_) { // __w right child is non-null and red __w->__right_->__is_black_ = true; __w->__is_black_ = false; __tree_left_rotate(__w); // __w is known not to be root, so root hasn't changed // reset sibling, and it still can't be null __w = __w->__parent_unsafe(); } // __w has a left red child, right child may be null __w->__is_black_ = __w->__parent_unsafe()->__is_black_; __w->__parent_unsafe()->__is_black_ = true; __w->__left_->__is_black_ = true; __tree_right_rotate(__w->__parent_unsafe()); break; } } } } } } // node traits #ifndef _LIBCPP_CXX03_LANG template struct __is_tree_value_type_imp : false_type {}; template struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {}; template struct __is_tree_value_type : false_type {}; template struct __is_tree_value_type<_One> : __is_tree_value_type_imp::type> {}; #endif template struct __tree_key_value_types { typedef _Tp key_type; typedef _Tp __node_value_type; typedef _Tp __container_value_type; static const bool __is_map = false; _LIBCPP_INLINE_VISIBILITY static key_type const& __get_key(_Tp const& __v) { return __v; } _LIBCPP_INLINE_VISIBILITY static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; } _LIBCPP_INLINE_VISIBILITY static __container_value_type* __get_ptr(__node_value_type& __n) { return _VSTD::addressof(__n); } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY static __container_value_type&& __move(__node_value_type& __v) { return _VSTD::move(__v); } #endif }; template struct __tree_key_value_types<__value_type<_Key, _Tp> > { typedef _Key key_type; typedef _Tp mapped_type; typedef __value_type<_Key, _Tp> __node_value_type; typedef pair __container_value_type; typedef pair<_Key, _Tp> __nc_value_type; typedef __container_value_type __map_value_type; static const bool __is_map = true; _LIBCPP_INLINE_VISIBILITY static key_type const& __get_key(__node_value_type const& __t) { return __t.__cc.first; } template _LIBCPP_INLINE_VISIBILITY static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, key_type const&>::type __get_key(_Up& __t) { return __t.first; } _LIBCPP_INLINE_VISIBILITY static __container_value_type const& __get_value(__node_value_type const& __t) { return __t.__cc; } template _LIBCPP_INLINE_VISIBILITY static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&>::type __get_value(_Up& __t) { return __t; } _LIBCPP_INLINE_VISIBILITY static __container_value_type* __get_ptr(__node_value_type& __n) { return _VSTD::addressof(__n.__cc); } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY static __nc_value_type&& __move(__node_value_type& __v) { return _VSTD::move(__v.__nc); } #endif }; template struct __tree_node_base_types { typedef _VoidPtr __void_pointer; typedef __tree_node_base<__void_pointer> __node_base_type; typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type __node_base_pointer; typedef __tree_end_node<__node_base_pointer> __end_node_type; typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type __end_node_pointer; #if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) typedef __end_node_pointer __parent_pointer; #else typedef typename conditional< is_pointer<__end_node_pointer>::value, __end_node_pointer, __node_base_pointer>::type __parent_pointer; #endif private: static_assert((is_same::element_type, void>::value), "_VoidPtr does not point to unqualified void type"); }; template , bool = _KVTypes::__is_map> struct __tree_map_pointer_types {}; template struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { typedef typename _KVTypes::__map_value_type _Mv; typedef typename __rebind_pointer<_AllocPtr, _Mv>::type __map_value_type_pointer; typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type __const_map_value_type_pointer; }; template ::element_type> struct __tree_node_types; template struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > : public __tree_node_base_types<_VoidPtr>, __tree_key_value_types<_Tp>, __tree_map_pointer_types<_Tp, _VoidPtr> { typedef __tree_node_base_types<_VoidPtr> __base; typedef __tree_key_value_types<_Tp> __key_base; typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; public: typedef typename pointer_traits<_NodePtr>::element_type __node_type; typedef _NodePtr __node_pointer; typedef _Tp __node_value_type; typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type __node_value_type_pointer; typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type __const_node_value_type_pointer; #if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) typedef typename __base::__end_node_pointer __iter_pointer; #else typedef typename conditional< is_pointer<__node_pointer>::value, typename __base::__end_node_pointer, __node_pointer>::type __iter_pointer; #endif private: static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const"); static_assert((is_same::type, _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); }; template struct __make_tree_node_types { typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type _NodePtr; typedef __tree_node_types<_NodePtr> type; }; // node template class __tree_end_node { public: typedef _Pointer pointer; pointer __left_; _LIBCPP_INLINE_VISIBILITY __tree_end_node() _NOEXCEPT : __left_() {} }; template class __tree_node_base : public __tree_node_base_types<_VoidPtr>::__end_node_type { typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; public: typedef typename _NodeBaseTypes::__node_base_pointer pointer; typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; pointer __right_; __parent_pointer __parent_; bool __is_black_; _LIBCPP_INLINE_VISIBILITY pointer __parent_unsafe() const { return static_cast(__parent_);} _LIBCPP_INLINE_VISIBILITY void __set_parent(pointer __p) { __parent_ = static_cast<__parent_pointer>(__p); } private: ~__tree_node_base() _LIBCPP_EQUAL_DELETE; __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; }; template class __tree_node : public __tree_node_base<_VoidPtr> { public: typedef _Tp __node_value_type; __node_value_type __value_; private: ~__tree_node() _LIBCPP_EQUAL_DELETE; __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE; __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE; }; template class __tree_node_destructor { typedef _Allocator allocator_type; typedef allocator_traits __alloc_traits; public: typedef typename __alloc_traits::pointer pointer; private: typedef __tree_node_types _NodeTypes; allocator_type& __na_; __tree_node_destructor& operator=(const __tree_node_destructor&); public: bool __value_constructed; _LIBCPP_INLINE_VISIBILITY explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT : __na_(__na), __value_constructed(__val) {} _LIBCPP_INLINE_VISIBILITY void operator()(pointer __p) _NOEXCEPT { if (__value_constructed) __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } template friend class __map_node_destructor; }; template class _LIBCPP_TYPE_VIS_ONLY __tree_iterator { typedef __tree_node_types<_NodePtr> _NodeTypes; typedef _NodePtr __node_pointer; typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; typedef typename _NodeTypes::__iter_pointer __iter_pointer; typedef pointer_traits<__node_pointer> __pointer_traits; __iter_pointer __ptr_; public: typedef bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _DiffType difference_type; typedef value_type& reference; typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 : __ptr_(nullptr) #endif {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __get_np()->__value_;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return pointer_traits::pointer_to(__get_np()->__value_);} _LIBCPP_INLINE_VISIBILITY __tree_iterator& operator++() { __ptr_ = static_cast<__iter_pointer>( __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY __tree_iterator operator++(int) {__tree_iterator __t(*this); ++(*this); return __t;} _LIBCPP_INLINE_VISIBILITY __tree_iterator& operator--() { __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( static_cast<__end_node_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY __tree_iterator operator--(int) {__tree_iterator __t(*this); --(*this); return __t;} friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) {return __x.__ptr_ == __y.__ptr_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) {return !(__x == __y);} private: _LIBCPP_INLINE_VISIBILITY explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} _LIBCPP_INLINE_VISIBILITY explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} _LIBCPP_INLINE_VISIBILITY __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } template friend class __tree; template friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; template friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator; template friend class _LIBCPP_TYPE_VIS_ONLY map; template friend class _LIBCPP_TYPE_VIS_ONLY multimap; template friend class _LIBCPP_TYPE_VIS_ONLY set; template friend class _LIBCPP_TYPE_VIS_ONLY multiset; }; template class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator { typedef __tree_node_types<_NodePtr> _NodeTypes; typedef typename _NodeTypes::__node_pointer __node_pointer; typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; typedef typename _NodeTypes::__iter_pointer __iter_pointer; typedef pointer_traits<__node_pointer> __pointer_traits; __iter_pointer __ptr_; public: typedef bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _DiffType difference_type; typedef const value_type& reference; typedef typename _NodeTypes::__const_node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 : __ptr_(nullptr) #endif {} private: typedef __tree_iterator __non_const_iterator; public: _LIBCPP_INLINE_VISIBILITY __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __get_np()->__value_;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return pointer_traits::pointer_to(__get_np()->__value_);} _LIBCPP_INLINE_VISIBILITY __tree_const_iterator& operator++() { __ptr_ = static_cast<__iter_pointer>( __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY __tree_const_iterator operator++(int) {__tree_const_iterator __t(*this); ++(*this); return __t;} _LIBCPP_INLINE_VISIBILITY __tree_const_iterator& operator--() { __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( static_cast<__end_node_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY __tree_const_iterator operator--(int) {__tree_const_iterator __t(*this); --(*this); return __t;} friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {return __x.__ptr_ == __y.__ptr_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {return !(__x == __y);} private: _LIBCPP_INLINE_VISIBILITY explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} _LIBCPP_INLINE_VISIBILITY explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} _LIBCPP_INLINE_VISIBILITY __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } template friend class __tree; template friend class _LIBCPP_TYPE_VIS_ONLY map; template friend class _LIBCPP_TYPE_VIS_ONLY multimap; template friend class _LIBCPP_TYPE_VIS_ONLY set; template friend class _LIBCPP_TYPE_VIS_ONLY multiset; template friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; }; template class __tree { public: typedef _Tp value_type; typedef _Compare value_compare; typedef _Allocator allocator_type; private: typedef allocator_traits __alloc_traits; typedef typename __make_tree_node_types::type _NodeTypes; typedef typename _NodeTypes::key_type key_type; public: typedef typename _NodeTypes::__node_value_type __node_value_type; typedef typename _NodeTypes::__container_value_type __container_value_type; typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __alloc_traits::size_type size_type; typedef typename __alloc_traits::difference_type difference_type; public: typedef typename _NodeTypes::__void_pointer __void_pointer; typedef typename _NodeTypes::__node_type __node; typedef typename _NodeTypes::__node_pointer __node_pointer; typedef typename _NodeTypes::__node_base_type __node_base; typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; typedef typename _NodeTypes::__end_node_type __end_node_t; typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; typedef typename _NodeTypes::__parent_pointer __parent_pointer; typedef typename _NodeTypes::__iter_pointer __iter_pointer; typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; typedef allocator_traits<__node_allocator> __node_traits; private: // check for sane allocator pointer rebinding semantics. Rebinding the // allocator for a new pointer type should be exactly the same as rebinding // the pointer using 'pointer_traits'. static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), "Allocator does not rebind pointers in a sane manner."); typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type __node_base_allocator; typedef allocator_traits<__node_base_allocator> __node_base_traits; static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), "Allocator does not rebind pointers in a sane manner."); private: __iter_pointer __begin_node_; __compressed_pair<__end_node_t, __node_allocator> __pair1_; __compressed_pair __pair3_; public: _LIBCPP_INLINE_VISIBILITY __iter_pointer __end_node() _NOEXCEPT { return static_cast<__iter_pointer>( pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) ); } _LIBCPP_INLINE_VISIBILITY __iter_pointer __end_node() const _NOEXCEPT { return static_cast<__iter_pointer>( pointer_traits<__end_node_ptr>::pointer_to( const_cast<__end_node_t&>(__pair1_.first()) ) ); } _LIBCPP_INLINE_VISIBILITY __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} private: _LIBCPP_INLINE_VISIBILITY const __node_allocator& __node_alloc() const _NOEXCEPT {return __pair1_.second();} _LIBCPP_INLINE_VISIBILITY __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} _LIBCPP_INLINE_VISIBILITY const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} public: _LIBCPP_INLINE_VISIBILITY allocator_type __alloc() const _NOEXCEPT {return allocator_type(__node_alloc());} private: _LIBCPP_INLINE_VISIBILITY size_type& size() _NOEXCEPT {return __pair3_.first();} public: _LIBCPP_INLINE_VISIBILITY const size_type& size() const _NOEXCEPT {return __pair3_.first();} _LIBCPP_INLINE_VISIBILITY value_compare& value_comp() _NOEXCEPT {return __pair3_.second();} _LIBCPP_INLINE_VISIBILITY const value_compare& value_comp() const _NOEXCEPT {return __pair3_.second();} public: _LIBCPP_INLINE_VISIBILITY __node_pointer __root() const _NOEXCEPT {return static_cast<__node_pointer>(__end_node()->__left_);} __node_base_pointer* __root_ptr() const _NOEXCEPT { return _VSTD::addressof(__end_node()->__left_); } typedef __tree_iterator iterator; typedef __tree_const_iterator const_iterator; explicit __tree(const value_compare& __comp) _NOEXCEPT_( is_nothrow_default_constructible<__node_allocator>::value && is_nothrow_copy_constructible::value); explicit __tree(const allocator_type& __a); __tree(const value_compare& __comp, const allocator_type& __a); __tree(const __tree& __t); __tree& operator=(const __tree& __t); template void __assign_unique(_InputIterator __first, _InputIterator __last); template void __assign_multi(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __tree(__tree&& __t) _NOEXCEPT_( is_nothrow_move_constructible<__node_allocator>::value && is_nothrow_move_constructible::value); __tree(__tree&& __t, const allocator_type& __a); __tree& operator=(__tree&& __t) _NOEXCEPT_( __node_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable<__node_allocator>::value); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~__tree(); _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return iterator(__begin_node());} _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());} _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return iterator(__end_node());} _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __node_traits::max_size(__node_alloc());} void clear() _NOEXCEPT; void swap(__tree& __t) _NOEXCEPT_( __is_nothrow_swappable::value #if _LIBCPP_STD_VER <= 11 && (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value) #endif ); #ifndef _LIBCPP_CXX03_LANG template pair __emplace_unique_key_args(_Key const&, _Args&&... __args); template iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); template pair __emplace_unique_impl(_Args&&... __args); template iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); template iterator __emplace_multi(_Args&&... __args); template iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique(_Pp&& __x) { return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>()); } template _LIBCPP_INLINE_VISIBILITY typename enable_if< __can_extract_map_key<_First, key_type, __container_value_type>::value, pair >::type __emplace_unique(_First&& __f, _Second&& __s) { return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), _VSTD::forward<_Second>(__s)); } template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique(_Args&&... __args) { return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); } template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); } template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); } template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); } template _LIBCPP_INLINE_VISIBILITY 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>()); } template _LIBCPP_INLINE_VISIBILITY typename enable_if< __can_extract_map_key<_First, key_type, __container_value_type>::value, iterator >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { return __emplace_hint_unique_key_args(__p, __f, _VSTD::forward<_First>(__f), _VSTD::forward<_Second>(__s)); } template _LIBCPP_INLINE_VISIBILITY iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); } template _LIBCPP_INLINE_VISIBILITY 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)); } template _LIBCPP_INLINE_VISIBILITY iterator __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); } template _LIBCPP_INLINE_VISIBILITY iterator __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); } #else template _LIBCPP_INLINE_VISIBILITY pair __emplace_unique_key_args(_Key const&, _Args& __args); template _LIBCPP_INLINE_VISIBILITY iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&); #endif _LIBCPP_INLINE_VISIBILITY pair __insert_unique(const __container_value_type& __v) { return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); } _LIBCPP_INLINE_VISIBILITY iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v); } #ifdef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY iterator __insert_multi(const __container_value_type& __v); _LIBCPP_INLINE_VISIBILITY iterator __insert_multi(const_iterator __p, const __container_value_type& __v); #else _LIBCPP_INLINE_VISIBILITY pair __insert_unique(__container_value_type&& __v) { return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v)); } _LIBCPP_INLINE_VISIBILITY iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)); } template ::type, __container_value_type >::value >::type> _LIBCPP_INLINE_VISIBILITY pair __insert_unique(_Vp&& __v) { return __emplace_unique(_VSTD::forward<_Vp>(__v)); } template ::type, __container_value_type >::value >::type> _LIBCPP_INLINE_VISIBILITY iterator __insert_unique(const_iterator __p, _Vp&& __v) { return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v)); } _LIBCPP_INLINE_VISIBILITY iterator __insert_multi(__container_value_type&& __v) { return __emplace_multi(_VSTD::move(__v)); } _LIBCPP_INLINE_VISIBILITY iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { return __emplace_hint_multi(__p, _VSTD::move(__v)); } template _LIBCPP_INLINE_VISIBILITY iterator __insert_multi(_Vp&& __v) { return __emplace_multi(_VSTD::forward<_Vp>(__v)); } template _LIBCPP_INLINE_VISIBILITY iterator __insert_multi(const_iterator __p, _Vp&& __v) { return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v)); } #endif // !_LIBCPP_CXX03_LANG pair __node_insert_unique(__node_pointer __nd); iterator __node_insert_unique(const_iterator __p, __node_pointer __nd); iterator __node_insert_multi(__node_pointer __nd); iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); iterator erase(const_iterator __p); iterator erase(const_iterator __f, const_iterator __l); template size_type __erase_unique(const _Key& __k); template size_type __erase_multi(const _Key& __k); void __insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node); template iterator find(const _Key& __v); template const_iterator find(const _Key& __v) const; template size_type __count_unique(const _Key& __k) const; template size_type __count_multi(const _Key& __k) const; template _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const _Key& __v) {return __lower_bound(__v, __root(), __end_node());} template iterator __lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result); template _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const _Key& __v) const {return __lower_bound(__v, __root(), __end_node());} template const_iterator __lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) const; template _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const _Key& __v) {return __upper_bound(__v, __root(), __end_node());} template iterator __upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result); template _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const _Key& __v) const {return __upper_bound(__v, __root(), __end_node());} template const_iterator __upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) const; template pair __equal_range_unique(const _Key& __k); template pair __equal_range_unique(const _Key& __k) const; template pair __equal_range_multi(const _Key& __k); template pair __equal_range_multi(const _Key& __k) const; typedef __tree_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; __node_holder remove(const_iterator __p) _NOEXCEPT; private: __node_base_pointer& __find_leaf_low(__parent_pointer& __parent, const key_type& __v); __node_base_pointer& __find_leaf_high(__parent_pointer& __parent, const key_type& __v); __node_base_pointer& __find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v); template __node_base_pointer& __find_equal(__parent_pointer& __parent, const _Key& __v); template __node_base_pointer& __find_equal(const_iterator __hint, __parent_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v); #ifndef _LIBCPP_CXX03_LANG template __node_holder __construct_node(_Args&& ...__args); #else __node_holder __construct_node(const __container_value_type& __v); #endif void destroy(__node_pointer __nd) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __tree& __t) {__copy_assign_alloc(__t, integral_constant());} _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __tree& __t, true_type) - {__node_alloc() = __t.__node_alloc();} + { + if (__node_alloc() != __t.__node_alloc()) + clear(); + __node_alloc() = __t.__node_alloc(); + } _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __tree& __t, false_type) {} void __move_assign(__tree& __t, false_type); void __move_assign(__tree& __t, true_type) _NOEXCEPT_(is_nothrow_move_assignable::value && is_nothrow_move_assignable<__node_allocator>::value); _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__tree& __t) _NOEXCEPT_( !__node_traits::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<__node_allocator>::value) {__move_assign_alloc(__t, integral_constant());} _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__tree& __t, true_type) _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {__node_alloc() = _VSTD::move(__t.__node_alloc());} _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {} __node_pointer __detach(); static __node_pointer __detach(__node_pointer); template friend class _LIBCPP_TYPE_VIS_ONLY map; template friend class _LIBCPP_TYPE_VIS_ONLY multimap; }; template __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) _NOEXCEPT_( is_nothrow_default_constructible<__node_allocator>::value && is_nothrow_copy_constructible::value) : __pair3_(0, __comp) { __begin_node() = __end_node(); } template __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) : __begin_node_(__iter_pointer()), __pair1_(__node_allocator(__a)), __pair3_(0) { __begin_node() = __end_node(); } template __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a) : __begin_node_(__iter_pointer()), __pair1_(__node_allocator(__a)), __pair3_(0, __comp) { __begin_node() = __end_node(); } // Precondition: size() != 0 template typename __tree<_Tp, _Compare, _Allocator>::__node_pointer __tree<_Tp, _Compare, _Allocator>::__detach() { __node_pointer __cache = static_cast<__node_pointer>(__begin_node()); __begin_node() = __end_node(); __end_node()->__left_->__parent_ = nullptr; __end_node()->__left_ = nullptr; size() = 0; // __cache->__left_ == nullptr if (__cache->__right_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__right_); // __cache->__left_ == nullptr // __cache->__right_ == nullptr return __cache; } // Precondition: __cache != nullptr // __cache->left_ == nullptr // __cache->right_ == nullptr // This is no longer a red-black tree template typename __tree<_Tp, _Compare, _Allocator>::__node_pointer __tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache) { if (__cache->__parent_ == nullptr) return nullptr; if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache))) { __cache->__parent_->__left_ = nullptr; __cache = static_cast<__node_pointer>(__cache->__parent_); if (__cache->__right_ == nullptr) return __cache; return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); } // __cache is right child __cache->__parent_unsafe()->__right_ = nullptr; __cache = static_cast<__node_pointer>(__cache->__parent_); if (__cache->__left_ == nullptr) return __cache; return static_cast<__node_pointer>(__tree_leaf(__cache->__left_)); } template __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) { if (this != &__t) { value_comp() = __t.value_comp(); __copy_assign_alloc(__t); __assign_multi(__t.begin(), __t.end()); } return *this; } template template void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last) { typedef iterator_traits<_InputIterator> _ITraits; typedef typename _ITraits::value_type _ItValueType; static_assert((is_same<_ItValueType, __container_value_type>::value), "__assign_unique may only be called with the containers value type"); if (size() != 0) { __node_pointer __cache = __detach(); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (; __cache != nullptr && __first != __last; ++__first) { __cache->__value_ = *__first; __node_pointer __next = __detach(__cache); __node_insert_unique(__cache); __cache = __next; } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { while (__cache->__parent_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__parent_); destroy(__cache); throw; } #endif // _LIBCPP_NO_EXCEPTIONS if (__cache != nullptr) { while (__cache->__parent_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__parent_); destroy(__cache); } } for (; __first != __last; ++__first) __insert_unique(*__first); } template template void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) { typedef iterator_traits<_InputIterator> _ITraits; typedef typename _ITraits::value_type _ItValueType; static_assert((is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value), "__assign_multi may only be called with the containers value type" " or the nodes value type"); if (size() != 0) { __node_pointer __cache = __detach(); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (; __cache != nullptr && __first != __last; ++__first) { __cache->__value_ = *__first; __node_pointer __next = __detach(__cache); __node_insert_multi(__cache); __cache = __next; } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { while (__cache->__parent_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__parent_); destroy(__cache); throw; } #endif // _LIBCPP_NO_EXCEPTIONS if (__cache != nullptr) { while (__cache->__parent_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__parent_); destroy(__cache); } } for (; __first != __last; ++__first) __insert_multi(_NodeTypes::__get_value(*__first)); } template __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) : __begin_node_(__iter_pointer()), __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())), __pair3_(0, __t.value_comp()) { __begin_node() = __end_node(); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_( is_nothrow_move_constructible<__node_allocator>::value && is_nothrow_move_constructible::value) : __begin_node_(_VSTD::move(__t.__begin_node_)), __pair1_(_VSTD::move(__t.__pair1_)), __pair3_(_VSTD::move(__t.__pair3_)) { if (size() == 0) __begin_node() = __end_node(); else { __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; } } template __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) : __pair1_(__node_allocator(__a)), __pair3_(0, _VSTD::move(__t.value_comp())) { if (__a == __t.__alloc()) { if (__t.size() == 0) __begin_node() = __end_node(); else { __begin_node() = __t.__begin_node(); __end_node()->__left_ = __t.__end_node()->__left_; __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); size() = __t.size(); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; } } else { __begin_node() = __end_node(); } } template void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) _NOEXCEPT_(is_nothrow_move_assignable::value && is_nothrow_move_assignable<__node_allocator>::value) { destroy(static_cast<__node_pointer>(__end_node()->__left_)); __begin_node_ = __t.__begin_node_; __pair1_.first() = __t.__pair1_.first(); __move_assign_alloc(__t); __pair3_ = _VSTD::move(__t.__pair3_); if (size() == 0) __begin_node() = __end_node(); else { __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; } } template void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) { if (__node_alloc() == __t.__node_alloc()) __move_assign(__t, true_type()); else { value_comp() = _VSTD::move(__t.value_comp()); const_iterator __e = end(); if (size() != 0) { __node_pointer __cache = __detach(); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS while (__cache != nullptr && __t.size() != 0) { __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_); __node_pointer __next = __detach(__cache); __node_insert_multi(__cache); __cache = __next; } #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { while (__cache->__parent_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__parent_); destroy(__cache); throw; } #endif // _LIBCPP_NO_EXCEPTIONS if (__cache != nullptr) { while (__cache->__parent_ != nullptr) __cache = static_cast<__node_pointer>(__cache->__parent_); destroy(__cache); } } while (__t.size() != 0) __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); } } template __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) _NOEXCEPT_( __node_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable<__node_allocator>::value) { __move_assign(__t, integral_constant()); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template __tree<_Tp, _Compare, _Allocator>::~__tree() { static_assert((is_copy_constructible::value), "Comparator must be copy-constructible."); destroy(__root()); } template void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT { if (__nd != nullptr) { destroy(static_cast<__node_pointer>(__nd->__left_)); destroy(static_cast<__node_pointer>(__nd->__right_)); __node_allocator& __na = __node_alloc(); __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); __node_traits::deallocate(__na, __nd, 1); } } template void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) _NOEXCEPT_( __is_nothrow_swappable::value #if _LIBCPP_STD_VER <= 11 && (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value) #endif ) { using _VSTD::swap; swap(__begin_node_, __t.__begin_node_); swap(__pair1_.first(), __t.__pair1_.first()); __swap_allocator(__node_alloc(), __t.__node_alloc()); __pair3_.swap(__t.__pair3_); if (size() == 0) __begin_node() = __end_node(); else __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); if (__t.size() == 0) __t.__begin_node() = __t.__end_node(); else __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); } template void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT { destroy(__root()); size() = 0; __begin_node() = __end_node(); __end_node()->__left_ = nullptr; } // Find lower_bound place to insert // Set __parent to parent of null leaf // Return reference to null leaf template typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, const key_type& __v) { __node_pointer __nd = __root(); if (__nd != nullptr) { while (true) { if (value_comp()(__nd->__value_, __v)) { if (__nd->__right_ != nullptr) __nd = static_cast<__node_pointer>(__nd->__right_); else { __parent = static_cast<__parent_pointer>(__nd); return __nd->__right_; } } else { if (__nd->__left_ != nullptr) __nd = static_cast<__node_pointer>(__nd->__left_); else { __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } } } __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } // Find upper_bound place to insert // Set __parent to parent of null leaf // Return reference to null leaf template typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, const key_type& __v) { __node_pointer __nd = __root(); if (__nd != nullptr) { while (true) { if (value_comp()(__v, __nd->__value_)) { if (__nd->__left_ != nullptr) __nd = static_cast<__node_pointer>(__nd->__left_); else { __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } else { if (__nd->__right_ != nullptr) __nd = static_cast<__node_pointer>(__nd->__right_); else { __parent = static_cast<__parent_pointer>(__nd); return __nd->__right_; } } } } __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } // Find leaf place to insert closest to __hint // First check prior to __hint. // Next check after __hint. // Next do O(log N) search. // Set __parent to parent of null leaf // Return reference to null leaf template typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v) { if (__hint == end() || !value_comp()(*__hint, __v)) // check before { // __v <= *__hint const_iterator __prior = __hint; if (__prior == begin() || !value_comp()(__v, *--__prior)) { // *prev(__hint) <= __v <= *__hint if (__hint.__ptr_->__left_ == nullptr) { __parent = static_cast<__parent_pointer>(__hint.__ptr_); return __parent->__left_; } else { __parent = static_cast<__parent_pointer>(__prior.__ptr_); return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; } } // __v < *prev(__hint) return __find_leaf_high(__parent, __v); } // else __v > *__hint return __find_leaf_low(__parent, __v); } // Find place to insert if __v doesn't exist // Set __parent to parent of null leaf // Return reference to null leaf // If __v exists, set parent to node of __v and return reference to node of __v template template typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, const _Key& __v) { __node_pointer __nd = __root(); __node_base_pointer* __nd_ptr = __root_ptr(); if (__nd != nullptr) { while (true) { if (value_comp()(__v, __nd->__value_)) { if (__nd->__left_ != nullptr) { __nd_ptr = _VSTD::addressof(__nd->__left_); __nd = static_cast<__node_pointer>(__nd->__left_); } else { __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } else if (value_comp()(__nd->__value_, __v)) { if (__nd->__right_ != nullptr) { __nd_ptr = _VSTD::addressof(__nd->__right_); __nd = static_cast<__node_pointer>(__nd->__right_); } else { __parent = static_cast<__parent_pointer>(__nd); return __nd->__right_; } } else { __parent = static_cast<__parent_pointer>(__nd); return *__nd_ptr; } } } __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } // Find place to insert if __v doesn't exist // First check prior to __hint. // Next check after __hint. // Next do O(log N) search. // Set __parent to parent of null leaf // Return reference to null leaf // If __v exists, set parent to node of __v and return reference to node of __v template template typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, __parent_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v) { if (__hint == end() || value_comp()(__v, *__hint)) // check before { // __v < *__hint const_iterator __prior = __hint; if (__prior == begin() || value_comp()(*--__prior, __v)) { // *prev(__hint) < __v < *__hint if (__hint.__ptr_->__left_ == nullptr) { __parent = static_cast<__parent_pointer>(__hint.__ptr_); return __parent->__left_; } else { __parent = static_cast<__parent_pointer>(__prior.__ptr_); return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; } } // __v <= *prev(__hint) return __find_equal(__parent, __v); } else if (value_comp()(*__hint, __v)) // check after { // *__hint < __v const_iterator __next = _VSTD::next(__hint); if (__next == end() || value_comp()(__v, *__next)) { // *__hint < __v < *_VSTD::next(__hint) if (__hint.__get_np()->__right_ == nullptr) { __parent = static_cast<__parent_pointer>(__hint.__ptr_); return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; } else { __parent = static_cast<__parent_pointer>(__next.__ptr_); return __parent->__left_; } } // *next(__hint) <= __v return __find_equal(__parent, __v); } // else __v == *__hint __parent = static_cast<__parent_pointer>(__hint.__ptr_); __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); return __dummy; } template void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) { __new_node->__left_ = nullptr; __new_node->__right_ = nullptr; __new_node->__parent_ = __parent; // __new_node->__is_black_ is initialized in __tree_balance_after_insert __child = __new_node; if (__begin_node()->__left_ != nullptr) __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); __tree_balance_after_insert(__end_node()->__left_, __child); ++size(); } #ifndef _LIBCPP_CXX03_LANG template template pair::iterator, bool> __tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) #else template template pair::iterator, bool> __tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args) #endif { __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __k); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; if (__child == nullptr) { #ifndef _LIBCPP_CXX03_LANG __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); #else __node_holder __h = __construct_node(__args); #endif __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); __r = __h.release(); __inserted = true; } return pair(iterator(__r), __inserted); } #ifndef _LIBCPP_CXX03_LANG template template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( const_iterator __p, _Key const& __k, _Args&&... __args) #else template template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( const_iterator __p, _Key const& __k, _Args& __args) #endif { __parent_pointer __parent; __node_base_pointer __dummy; __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) { #ifndef _LIBCPP_CXX03_LANG __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); #else __node_holder __h = __construct_node(__args); #endif __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); __r = __h.release(); } return iterator(__r); } #ifndef _LIBCPP_CXX03_LANG template template typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) { static_assert(!__is_tree_value_type<_Args...>::value, "Cannot construct from __value_type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; return __h; } template template pair::iterator, bool> __tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __h->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; if (__child == nullptr) { __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); __r = __h.release(); __inserted = true; } return pair(iterator(__r), __inserted); } template template 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); } template template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); __parent_pointer __parent; __node_base_pointer& __child = __find_leaf_high(__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())); } template template 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())); } #else // _LIBCPP_CXX03_LANG template typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } #endif // _LIBCPP_CXX03_LANG #ifdef _LIBCPP_CXX03_LANG template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v) { __parent_pointer __parent; __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v)); __node_holder __h = __construct_node(__v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(__h.release()); } template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v) { __parent_pointer __parent; __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v)); __node_holder __h = __construct_node(__v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(__h.release()); } #endif template pair::iterator, bool> __tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd) { __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __nd->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; if (__child == nullptr) { __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); __r = __nd; __inserted = true; } return pair(iterator(__r), __inserted); } template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p, __node_pointer __nd) { __parent_pointer __parent; __node_base_pointer __dummy; __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) { __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); __r = __nd; } return iterator(__r); } template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) { __parent_pointer __parent; __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); return iterator(__nd); } template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) { __parent_pointer __parent; __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); return iterator(__nd); } template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) { __node_pointer __np = __p.__get_np(); iterator __r(__p.__ptr_); ++__r; if (__begin_node() == __p.__ptr_) __begin_node() = __r.__ptr_; --size(); __node_allocator& __na = __node_alloc(); __tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np)); __node_traits::destroy(__na, _NodeTypes::__get_ptr( const_cast<__node_value_type&>(*__p))); __node_traits::deallocate(__na, __np, 1); return __r; } template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) { while (__f != __l) __f = erase(__f); return iterator(__l.__ptr_); } template template typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) { iterator __i = find(__k); if (__i == end()) return 0; erase(__i); return 1; } template template typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) { pair __p = __equal_range_multi(__k); size_type __r = 0; for (; __p.first != __p.second; ++__r) __p.first = erase(__p.first); return __r; } template template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) { iterator __p = __lower_bound(__v, __root(), __end_node()); if (__p != end() && !value_comp()(__v, *__p)) return __p; return end(); } template template typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const { const_iterator __p = __lower_bound(__v, __root(), __end_node()); if (__p != end() && !value_comp()(__v, *__p)) return __p; return end(); } template template typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const { __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else return 1; } return 0; } template template typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const { __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else return _VSTD::distance( __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result) ); } return 0; } template template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) { while (__root != nullptr) { if (!value_comp()(__root->__value_, __v)) { __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else __root = static_cast<__node_pointer>(__root->__right_); } return iterator(__result); } template template typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) const { while (__root != nullptr) { if (!value_comp()(__root->__value_, __v)) { __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else __root = static_cast<__node_pointer>(__root->__right_); } return const_iterator(__result); } template template typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) { while (__root != nullptr) { if (value_comp()(__v, __root->__value_)) { __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else __root = static_cast<__node_pointer>(__root->__right_); } return iterator(__result); } template template typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __iter_pointer __result) const { while (__root != nullptr) { if (value_comp()(__v, __root->__value_)) { __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else __root = static_cast<__node_pointer>(__root->__right_); } return const_iterator(__result); } template template pair::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator> __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) { typedef pair _Pp; __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else return _Pp(iterator(__rt), iterator( __rt->__right_ != nullptr ? static_cast<__iter_pointer>(__tree_min(__rt->__right_)) : __result)); } return _Pp(iterator(__result), iterator(__result)); } template template pair::const_iterator, typename __tree<_Tp, _Compare, _Allocator>::const_iterator> __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const { typedef pair _Pp; __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else return _Pp(const_iterator(__rt), const_iterator( __rt->__right_ != nullptr ? static_cast<__iter_pointer>(__tree_min(__rt->__right_)) : __result)); } return _Pp(const_iterator(__result), const_iterator(__result)); } template template pair::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator> __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) { typedef pair _Pp; __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); } return _Pp(iterator(__result), iterator(__result)); } template template pair::const_iterator, typename __tree<_Tp, _Compare, _Allocator>::const_iterator> __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const { typedef pair _Pp; __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); } return _Pp(const_iterator(__result), const_iterator(__result)); } template typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT { __node_pointer __np = __p.__get_np(); if (__begin_node() == __p.__ptr_) { if (__np->__right_ != nullptr) __begin_node() = static_cast<__iter_pointer>(__np->__right_); else __begin_node() = static_cast<__iter_pointer>(__np->__parent_); } --size(); __tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np)); return __node_holder(__np, _Dp(__node_alloc(), true)); } template inline _LIBCPP_INLINE_VISIBILITY void swap(__tree<_Tp, _Compare, _Allocator>& __x, __tree<_Tp, _Compare, _Allocator>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___TREE Index: vendor/libc++/dist/include/map =================================================================== --- vendor/libc++/dist/include/map (revision 304764) +++ vendor/libc++/dist/include/map (revision 304765) @@ -1,2004 +1,2004 @@ // -*- C++ -*- //===----------------------------- map ------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_MAP #define _LIBCPP_MAP /* map synopsis namespace std { template , class Allocator = allocator>> class map { public: // types: typedef Key key_type; typedef T mapped_type; typedef pair value_type; typedef Compare key_compare; typedef Allocator allocator_type; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; typedef implementation-defined iterator; typedef implementation-defined const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; class value_compare : public binary_function { friend class map; protected: key_compare comp; value_compare(key_compare c); public: bool operator()(const value_type& x, const value_type& y) const; }; // construct/copy/destroy: map() noexcept( is_nothrow_default_constructible::value && is_nothrow_default_constructible::value && is_nothrow_copy_constructible::value); explicit map(const key_compare& comp); map(const key_compare& comp, const allocator_type& a); template map(InputIterator first, InputIterator last, const key_compare& comp = key_compare()); template map(InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a); map(const map& m); map(map&& m) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); explicit map(const allocator_type& a); map(const map& m, const allocator_type& a); map(map&& m, const allocator_type& a); map(initializer_list il, const key_compare& comp = key_compare()); map(initializer_list il, const key_compare& comp, const allocator_type& a); template map(InputIterator first, InputIterator last, const allocator_type& a) : map(first, last, Compare(), a) {} // C++14 map(initializer_list il, const allocator_type& a) : map(il, Compare(), a) {} // C++14 ~map(); map& operator=(const map& m); map& operator=(map&& m) noexcept( allocator_type::propagate_on_container_move_assignment::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); map& operator=(initializer_list il); // iterators: iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; const_iterator end() const noexcept; reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; // capacity: bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; // element access: mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; // modifiers: template pair emplace(Args&&... args); template iterator emplace_hint(const_iterator position, Args&&... args); pair insert(const value_type& v); pair insert( value_type&& v); // C++17 template pair insert(P&& p); iterator insert(const_iterator position, const value_type& v); iterator insert(const_iterator position, value_type&& v); // C++17 template iterator insert(const_iterator position, P&& p); template void insert(InputIterator first, InputIterator last); void insert(initializer_list il); template pair try_emplace(const key_type& k, Args&&... args); // C++17 template pair try_emplace(key_type&& k, Args&&... args); // C++17 template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 template pair insert_or_assign(const key_type& k, M&& obj); // C++17 template pair insert_or_assign(key_type&& k, M&& obj); // C++17 template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); iterator erase(const_iterator first, const_iterator last); void clear() noexcept; void swap(map& m) noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable::value); // C++17 // observers: allocator_type get_allocator() const noexcept; key_compare key_comp() const; value_compare value_comp() const; // map operations: iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& x); // C++14 template const_iterator find(const K& x) const; // C++14 template size_type count(const K& x) const; // C++14 size_type count(const key_type& k) const; iterator lower_bound(const key_type& k); const_iterator lower_bound(const key_type& k) const; template iterator lower_bound(const K& x); // C++14 template const_iterator lower_bound(const K& x) const; // C++14 iterator upper_bound(const key_type& k); const_iterator upper_bound(const key_type& k) const; template iterator upper_bound(const K& x); // C++14 template const_iterator upper_bound(const K& x) const; // C++14 pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; template pair equal_range(const K& x); // C++14 template pair equal_range(const K& x) const; // C++14 }; template bool operator==(const map& x, const map& y); template bool operator< (const map& x, const map& y); template bool operator!=(const map& x, const map& y); template bool operator> (const map& x, const map& y); template bool operator>=(const map& x, const map& y); template bool operator<=(const map& x, const map& y); // specialized algorithms: template void swap(map& x, map& y) noexcept(noexcept(x.swap(y))); template , class Allocator = allocator>> class multimap { public: // types: typedef Key key_type; typedef T mapped_type; typedef pair value_type; typedef Compare key_compare; typedef Allocator allocator_type; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef implementation-defined iterator; typedef implementation-defined const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; class value_compare : public binary_function { friend class multimap; protected: key_compare comp; value_compare(key_compare c); public: bool operator()(const value_type& x, const value_type& y) const; }; // construct/copy/destroy: multimap() noexcept( is_nothrow_default_constructible::value && is_nothrow_default_constructible::value && is_nothrow_copy_constructible::value); explicit multimap(const key_compare& comp); multimap(const key_compare& comp, const allocator_type& a); template multimap(InputIterator first, InputIterator last, const key_compare& comp); template multimap(InputIterator first, InputIterator last, const key_compare& comp, const allocator_type& a); multimap(const multimap& m); multimap(multimap&& m) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); explicit multimap(const allocator_type& a); multimap(const multimap& m, const allocator_type& a); multimap(multimap&& m, const allocator_type& a); multimap(initializer_list il, const key_compare& comp = key_compare()); multimap(initializer_list il, const key_compare& comp, const allocator_type& a); template multimap(InputIterator first, InputIterator last, const allocator_type& a) : multimap(first, last, Compare(), a) {} // C++14 multimap(initializer_list il, const allocator_type& a) : multimap(il, Compare(), a) {} // C++14 ~multimap(); multimap& operator=(const multimap& m); multimap& operator=(multimap&& m) noexcept( allocator_type::propagate_on_container_move_assignment::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); multimap& operator=(initializer_list il); // iterators: iterator begin() noexcept; const_iterator begin() const noexcept; iterator end() noexcept; const_iterator end() const noexcept; reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; // capacity: bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; // modifiers: template iterator emplace(Args&&... args); template iterator emplace_hint(const_iterator position, Args&&... args); iterator insert(const value_type& v); iterator insert( value_type&& v); // C++17 template iterator insert(P&& p); iterator insert(const_iterator position, const value_type& v); iterator insert(const_iterator position, value_type&& v); // C++17 template iterator insert(const_iterator position, P&& p); template void insert(InputIterator first, InputIterator last); void insert(initializer_list il); iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); iterator erase(const_iterator first, const_iterator last); void clear() noexcept; void swap(multimap& m) noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable::value); // C++17 // observers: allocator_type get_allocator() const noexcept; key_compare key_comp() const; value_compare value_comp() const; // map operations: iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& x); // C++14 template const_iterator find(const K& x) const; // C++14 template size_type count(const K& x) const; // C++14 size_type count(const key_type& k) const; iterator lower_bound(const key_type& k); const_iterator lower_bound(const key_type& k) const; template iterator lower_bound(const K& x); // C++14 template const_iterator lower_bound(const K& x) const; // C++14 iterator upper_bound(const key_type& k); const_iterator upper_bound(const key_type& k) const; template iterator upper_bound(const K& x); // C++14 template const_iterator upper_bound(const K& x) const; // C++14 pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; template pair equal_range(const K& x); // C++14 template pair equal_range(const K& x) const; // C++14 }; template bool operator==(const multimap& x, const multimap& y); template bool operator< (const multimap& x, const multimap& y); template bool operator!=(const multimap& x, const multimap& y); template bool operator> (const multimap& x, const multimap& y); template bool operator>=(const multimap& x, const multimap& y); template bool operator<=(const multimap& x, const multimap& y); // specialized algorithms: template void swap(multimap& x, multimap& y) noexcept(noexcept(x.swap(y))); } // std */ #include <__config> #include <__tree> #include #include #include #include #include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD template ::value && !__libcpp_is_final<_Compare>::value > class __map_value_compare : private _Compare { public: _LIBCPP_INLINE_VISIBILITY __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value) : _Compare() {} _LIBCPP_INLINE_VISIBILITY __map_value_compare(_Compare c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value) : _Compare(c) {} _LIBCPP_INLINE_VISIBILITY const _Compare& key_comp() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _CP& __y) const {return static_cast(*this)(__x.__cc.first, __y.__cc.first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _Key& __y) const {return static_cast(*this)(__x.__cc.first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _CP& __y) const {return static_cast(*this)(__x, __y.__cc.first);} void swap(__map_value_compare&__y) _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) { using _VSTD::swap; swap(static_cast(*this), static_cast(__y)); } #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () ( const _K2& __x, const _CP& __y ) const {return static_cast(*this) (__x, __y.__cc.first);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () (const _CP& __x, const _K2& __y) const {return static_cast(*this) (__x.__cc.first, __y);} #endif }; template class __map_value_compare<_Key, _CP, _Compare, false> { _Compare comp; public: _LIBCPP_INLINE_VISIBILITY __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value) : comp() {} _LIBCPP_INLINE_VISIBILITY __map_value_compare(_Compare c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value) : comp(c) {} _LIBCPP_INLINE_VISIBILITY const _Compare& key_comp() const _NOEXCEPT {return comp;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _CP& __y) const {return comp(__x.__cc.first, __y.__cc.first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _Key& __y) const {return comp(__x.__cc.first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _CP& __y) const {return comp(__x, __y.__cc.first);} void swap(__map_value_compare&__y) _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) { using _VSTD::swap; swap(comp, __y.comp); } #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () ( const _K2& __x, const _CP& __y ) const {return comp (__x, __y.__cc.first);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () (const _CP& __x, const _K2& __y) const {return comp (__x.__cc.first, __y);} #endif }; template inline _LIBCPP_INLINE_VISIBILITY void swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x, __map_value_compare<_Key, _CP, _Compare, __b>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } template class __map_node_destructor { typedef _Allocator allocator_type; typedef allocator_traits __alloc_traits; public: typedef typename __alloc_traits::pointer pointer; private: allocator_type& __na_; __map_node_destructor& operator=(const __map_node_destructor&); public: bool __first_constructed; bool __second_constructed; _LIBCPP_INLINE_VISIBILITY explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT : __na_(__na), __first_constructed(false), __second_constructed(false) {} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY __map_node_destructor(__tree_node_destructor&& __x) _NOEXCEPT : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) { __x.__value_constructed = false; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void operator()(pointer __p) _NOEXCEPT { if (__second_constructed) __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second)); if (__first_constructed) __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } }; template class map; template class multimap; template class __map_const_iterator; #ifndef _LIBCPP_CXX03_LANG template union __value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; typedef pair __nc_value_type; value_type __cc; __nc_value_type __nc; _LIBCPP_INLINE_VISIBILITY __value_type& operator=(const __value_type& __v) {__nc = __v.__cc; return *this;} _LIBCPP_INLINE_VISIBILITY __value_type& operator=(__value_type&& __v) {__nc = _VSTD::move(__v.__nc); return *this;} template ::value >::type > _LIBCPP_INLINE_VISIBILITY __value_type& operator=(_ValueTp&& __v) { __nc = _VSTD::forward<_ValueTp>(__v); return *this; } private: __value_type() _LIBCPP_EQUAL_DELETE; ~__value_type() _LIBCPP_EQUAL_DELETE; __value_type(const __value_type& __v) _LIBCPP_EQUAL_DELETE; __value_type(__value_type&& __v) _LIBCPP_EQUAL_DELETE; }; #else template struct __value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; value_type __cc; private: __value_type(); __value_type(__value_type const&); __value_type& operator=(__value_type const&); ~__value_type(); }; #endif template struct __extract_key_value_types; template struct __extract_key_value_types<__value_type<_Key, _Tp> > { typedef _Key const __key_type; typedef _Tp __mapped_type; }; template class _LIBCPP_TYPE_VIS_ONLY __map_iterator { typedef typename _TreeIterator::_NodeTypes _NodeTypes; typedef typename _TreeIterator::__pointer_traits __pointer_traits; _TreeIterator __i_; public: typedef bidirectional_iterator_tag iterator_category; typedef typename _NodeTypes::__map_value_type value_type; typedef typename _TreeIterator::difference_type difference_type; typedef value_type& reference; typedef typename _NodeTypes::__map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __map_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __i_->__cc;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return pointer_traits::pointer_to(__i_->__cc);} _LIBCPP_INLINE_VISIBILITY __map_iterator& operator++() {++__i_; return *this;} _LIBCPP_INLINE_VISIBILITY __map_iterator operator++(int) { __map_iterator __t(*this); ++(*this); return __t; } _LIBCPP_INLINE_VISIBILITY __map_iterator& operator--() {--__i_; return *this;} _LIBCPP_INLINE_VISIBILITY __map_iterator operator--(int) { __map_iterator __t(*this); --(*this); return __t; } friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __map_iterator& __x, const __map_iterator& __y) {return __x.__i_ == __y.__i_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __map_iterator& __x, const __map_iterator& __y) {return __x.__i_ != __y.__i_;} template friend class _LIBCPP_TYPE_VIS_ONLY map; template friend class _LIBCPP_TYPE_VIS_ONLY multimap; template friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; }; template class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator { typedef typename _TreeIterator::_NodeTypes _NodeTypes; typedef typename _TreeIterator::__pointer_traits __pointer_traits; _TreeIterator __i_; public: typedef bidirectional_iterator_tag iterator_category; typedef typename _NodeTypes::__map_value_type value_type; typedef typename _TreeIterator::difference_type difference_type; typedef const value_type& reference; typedef typename _NodeTypes::__const_map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __map_const_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY __map_const_iterator(__map_iterator< typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT : __i_(__i.__i_) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __i_->__cc;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return pointer_traits::pointer_to(__i_->__cc);} _LIBCPP_INLINE_VISIBILITY __map_const_iterator& operator++() {++__i_; return *this;} _LIBCPP_INLINE_VISIBILITY __map_const_iterator operator++(int) { __map_const_iterator __t(*this); ++(*this); return __t; } _LIBCPP_INLINE_VISIBILITY __map_const_iterator& operator--() {--__i_; return *this;} _LIBCPP_INLINE_VISIBILITY __map_const_iterator operator--(int) { __map_const_iterator __t(*this); --(*this); return __t; } friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) {return __x.__i_ == __y.__i_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) {return __x.__i_ != __y.__i_;} template friend class _LIBCPP_TYPE_VIS_ONLY map; template friend class _LIBCPP_TYPE_VIS_ONLY multimap; template friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; }; template , class _Allocator = allocator > > class _LIBCPP_TYPE_VIS_ONLY map { public: // types: typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; typedef pair __nc_value_type; typedef _Compare key_compare; typedef _Allocator allocator_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); class _LIBCPP_TYPE_VIS_ONLY value_compare : public binary_function { friend class map; protected: key_compare comp; _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {} public: _LIBCPP_INLINE_VISIBILITY bool operator()(const value_type& __x, const value_type& __y) const {return comp(__x.first, __y.first);} }; private: typedef _VSTD::__value_type __value_type; typedef __map_value_compare __vc; typedef typename __rebind_alloc_helper, __value_type>::type __allocator_type; typedef __tree<__value_type, __vc, __allocator_type> __base; typedef typename __base::__node_traits __node_traits; typedef allocator_traits __alloc_traits; __base __tree_; public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __alloc_traits::size_type size_type; typedef typename __alloc_traits::difference_type difference_type; typedef __map_iterator iterator; typedef __map_const_iterator const_iterator; typedef _VSTD::reverse_iterator reverse_iterator; typedef _VSTD::reverse_iterator const_reverse_iterator; _LIBCPP_INLINE_VISIBILITY map() _NOEXCEPT_( is_nothrow_default_constructible::value && is_nothrow_default_constructible::value && is_nothrow_copy_constructible::value) : __tree_(__vc(key_compare())) {} _LIBCPP_INLINE_VISIBILITY explicit map(const key_compare& __comp) _NOEXCEPT_( is_nothrow_default_constructible::value && is_nothrow_copy_constructible::value) : __tree_(__vc(__comp)) {} _LIBCPP_INLINE_VISIBILITY explicit map(const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) {} + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {} template _LIBCPP_INLINE_VISIBILITY map(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare()) : __tree_(__vc(__comp)) { insert(__f, __l); } template _LIBCPP_INLINE_VISIBILITY map(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__f, __l); } #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY map(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : map(__f, __l, key_compare(), __a) {} #endif _LIBCPP_INLINE_VISIBILITY map(const map& __m) : __tree_(__m.__tree_) { insert(__m.begin(), __m.end()); } _LIBCPP_INLINE_VISIBILITY map& operator=(const map& __m) { #ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else if (this != &__m) { __tree_.clear(); __tree_.value_comp() = __m.__tree_.value_comp(); __tree_.__copy_assign_alloc(__m.__tree_); insert(__m.begin(), __m.end()); } #endif return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY map(map&& __m) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) : __tree_(_VSTD::move(__m.__tree_)) { } map(map&& __m, const allocator_type& __a); _LIBCPP_INLINE_VISIBILITY map& operator=(map&& __m) _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) { __tree_ = _VSTD::move(__m.__tree_); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY map(initializer_list __il, const key_compare& __comp = key_compare()) : __tree_(__vc(__comp)) { insert(__il.begin(), __il.end()); } _LIBCPP_INLINE_VISIBILITY map(initializer_list __il, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__il.begin(), __il.end()); } #if _LIBCPP_STD_VER > 11 _LIBCPP_INLINE_VISIBILITY map(initializer_list __il, const allocator_type& __a) : map(__il, key_compare(), __a) {} #endif _LIBCPP_INLINE_VISIBILITY map& operator=(initializer_list __il) { __tree_.__assign_unique(__il.begin(), __il.end()); return *this; } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY explicit map(const allocator_type& __a) - : __tree_(__a) + : __tree_(typename __base::allocator_type(__a)) { } _LIBCPP_INLINE_VISIBILITY map(const map& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), __a) + : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) { insert(__m.begin(), __m.end()); } _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __tree_.begin();} _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __tree_.begin();} _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __tree_.end();} _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __tree_.end();} _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const _NOEXCEPT {return begin();} _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return end();} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const _NOEXCEPT {return rend();} _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __tree_.size() == 0;} _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __tree_.size();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __tree_.max_size();} mapped_type& operator[](const key_type& __k); #ifndef _LIBCPP_CXX03_LANG mapped_type& operator[](key_type&& __k); #endif mapped_type& at(const key_type& __k); const mapped_type& at(const key_type& __k) const; _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} _LIBCPP_INLINE_VISIBILITY key_compare key_comp() const {return __tree_.value_comp().key_comp();} _LIBCPP_INLINE_VISIBILITY value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} #ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY pair emplace(_Args&& ...__args) { return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...); } template _LIBCPP_INLINE_VISIBILITY iterator emplace_hint(const_iterator __p, _Args&& ...__args) { return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...); } template ::value>::type> _LIBCPP_INLINE_VISIBILITY pair insert(_Pp&& __p) {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));} template ::value>::type> _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __pos, _Pp&& __p) {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));} #endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair insert(const value_type& __v) {return __tree_.__insert_unique(__v);} _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, const value_type& __v) {return __tree_.__insert_unique(__p.__i_, __v);} #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));} _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, value_type&& __v) {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));} #endif template _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __f, _InputIterator __l) { for (const_iterator __e = cend(); __f != __l; ++__f) insert(__e.__i_, *__f); } #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY void insert(initializer_list __il) {insert(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #if _LIBCPP_STD_VER > 14 template _LIBCPP_INLINE_VISIBILITY pair try_emplace(const key_type& __k, _Args&&... __args) { return __tree_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template _LIBCPP_INLINE_VISIBILITY pair try_emplace(key_type&& __k, _Args&&... __args) { return __tree_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template _LIBCPP_INLINE_VISIBILITY pair insert_or_assign(const key_type& __k, _Vp&& __v) { iterator __p = lower_bound(__k); if ( __p != end() && !key_comp()(__k, __p->first)) { __p->second = _VSTD::forward<_Vp>(__v); return _VSTD::make_pair(__p, false); } return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true); } template _LIBCPP_INLINE_VISIBILITY pair insert_or_assign(key_type&& __k, _Vp&& __v) { iterator __p = lower_bound(__k); if ( __p != end() && !key_comp()(__k, __p->first)) { __p->second = _VSTD::forward<_Vp>(__v); return _VSTD::make_pair(__p, false); } return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true); } template _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) { iterator __p = lower_bound(__k); if ( __p != end() && !key_comp()(__k, __p->first)) { __p->second = _VSTD::forward<_Vp>(__v); return __p; } return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v)); } template _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) { iterator __p = lower_bound(__k); if ( __p != end() && !key_comp()(__k, __p->first)) { __p->second = _VSTD::forward<_Vp>(__v); return __p; } return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); } #endif _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY iterator erase(iterator __p) {return __tree_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY size_type erase(const key_type& __k) {return __tree_.__erase_unique(__k);} _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __f, const_iterator __l) {return __tree_.erase(__f.__i_, __l.__i_);} _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__tree_.clear();} _LIBCPP_INLINE_VISIBILITY void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable<__base>::value) {__tree_.swap(__m.__tree_);} _LIBCPP_INLINE_VISIBILITY iterator find(const key_type& __k) {return __tree_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __tree_.find(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type find(const _K2& __k) {return __tree_.find(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type find(const _K2& __k) const {return __tree_.find(__k);} #endif _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_unique(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type count(const _K2& __k) const {return __tree_.__count_unique(__k);} #endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) {return __tree_.lower_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const key_type& __k) const {return __tree_.lower_bound(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} #endif _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const key_type& __k) {return __tree_.upper_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const key_type& __k) const {return __tree_.upper_bound(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} #endif _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) {return __tree_.__equal_range_unique(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) const {return __tree_.__equal_range_unique(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);} #endif private: typedef typename __base::__node __node; typedef typename __base::__node_allocator __node_allocator; typedef typename __base::__node_pointer __node_pointer; typedef typename __base::__node_base_pointer __node_base_pointer; typedef __map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; #ifdef _LIBCPP_CXX03_LANG __node_holder __construct_node_with_key(const key_type& __k); #endif __node_base_pointer const& __find_equal_key(__node_base_pointer& __parent, const key_type& __k) const; _LIBCPP_INLINE_VISIBILITY __node_base_pointer& __find_equal_key(__node_base_pointer& __parent, const key_type& __k) { map const* __const_this = this; return const_cast<__node_base_pointer&>( __const_this->__find_equal_key(__parent, __k)); } }; // Find __k // Set __parent to parent of null leaf and // return reference to null leaf iv __k does not exist. // If __k exists, set parent to node of __k and return reference to node of __k template typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer const& map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent, const key_type& __k) const { __node_pointer __nd = __tree_.__root(); if (__nd != nullptr) { while (true) { if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first)) { if (__nd->__left_ != nullptr) __nd = static_cast<__node_pointer>(__nd->__left_); else { __parent = static_cast<__node_base_pointer>(__nd); return __parent->__left_; } } else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) { if (__nd->__right_ != nullptr) __nd = static_cast<__node_pointer>(__nd->__right_); else { __parent = static_cast<__node_base_pointer>(__nd); return __parent->__right_; } } else { __parent = static_cast<__node_base_pointer>(__nd); return __parent; } } } __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); return __parent->__left_; } #ifndef _LIBCPP_CXX03_LANG template map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) - : __tree_(_VSTD::move(__m.__tree_), __a) + : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a)) { if (__a != __m.get_allocator()) { const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_unique(__e.__i_, _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); } } #endif // !_LIBCPP_CXX03_LANG #ifdef _LIBCPP_CXX03_LANG template typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) { __node_allocator& __na = __tree_.__node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k); __h.get_deleter().__first_constructed = true; __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); __h.get_deleter().__second_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } template _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) { __node_base_pointer __parent; __node_base_pointer& __child = __find_equal_key(__parent, __k); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) { __node_holder __h = __construct_node_with_key(__k); __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); __r = __h.release(); } return __r->__value_.__cc.second; } #else template _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) { return __tree_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), _VSTD::forward_as_tuple()).first->__cc.second; } template _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) { return __tree_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), _VSTD::forward_as_tuple()).first->__cc.second; } #endif // !_LIBCPP_CXX03_LANG template _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) { __node_base_pointer __parent; __node_base_pointer& __child = __find_equal_key(__parent, __k); #ifndef _LIBCPP_NO_EXCEPTIONS if (__child == nullptr) throw out_of_range("map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS return static_cast<__node_pointer>(__child)->__value_.__cc.second; } template const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const { __node_base_pointer __parent; __node_base_pointer __child = __find_equal_key(__parent, __k); #ifndef _LIBCPP_NO_EXCEPTIONS if (__child == nullptr) throw out_of_range("map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS return static_cast<__node_pointer>(__child)->__value_.__cc.second; } template inline _LIBCPP_INLINE_VISIBILITY bool operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); } template inline _LIBCPP_INLINE_VISIBILITY bool operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { return !(__x == __y); } template inline _LIBCPP_INLINE_VISIBILITY bool operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { return __y < __x; } template inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { return !(__x < __y); } template inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { return !(__y < __x); } template inline _LIBCPP_INLINE_VISIBILITY void swap(map<_Key, _Tp, _Compare, _Allocator>& __x, map<_Key, _Tp, _Compare, _Allocator>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } template , class _Allocator = allocator > > class _LIBCPP_TYPE_VIS_ONLY multimap { public: // types: typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; typedef pair __nc_value_type; typedef _Compare key_compare; typedef _Allocator allocator_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); class _LIBCPP_TYPE_VIS_ONLY value_compare : public binary_function { friend class multimap; protected: key_compare comp; _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {} public: _LIBCPP_INLINE_VISIBILITY bool operator()(const value_type& __x, const value_type& __y) const {return comp(__x.first, __y.first);} }; private: typedef _VSTD::__value_type __value_type; typedef __map_value_compare __vc; typedef typename __rebind_alloc_helper, __value_type>::type __allocator_type; typedef __tree<__value_type, __vc, __allocator_type> __base; typedef typename __base::__node_traits __node_traits; typedef allocator_traits __alloc_traits; __base __tree_; public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __alloc_traits::size_type size_type; typedef typename __alloc_traits::difference_type difference_type; typedef __map_iterator iterator; typedef __map_const_iterator const_iterator; typedef _VSTD::reverse_iterator reverse_iterator; typedef _VSTD::reverse_iterator const_reverse_iterator; _LIBCPP_INLINE_VISIBILITY multimap() _NOEXCEPT_( is_nothrow_default_constructible::value && is_nothrow_default_constructible::value && is_nothrow_copy_constructible::value) : __tree_(__vc(key_compare())) {} _LIBCPP_INLINE_VISIBILITY explicit multimap(const key_compare& __comp) _NOEXCEPT_( is_nothrow_default_constructible::value && is_nothrow_copy_constructible::value) : __tree_(__vc(__comp)) {} _LIBCPP_INLINE_VISIBILITY explicit multimap(const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) {} + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {} template _LIBCPP_INLINE_VISIBILITY multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare()) : __tree_(__vc(__comp)) { insert(__f, __l); } template _LIBCPP_INLINE_VISIBILITY multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__f, __l); } #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : multimap(__f, __l, key_compare(), __a) {} #endif _LIBCPP_INLINE_VISIBILITY multimap(const multimap& __m) : __tree_(__m.__tree_.value_comp(), __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc())) { insert(__m.begin(), __m.end()); } _LIBCPP_INLINE_VISIBILITY multimap& operator=(const multimap& __m) { #ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else if (this != &__m) { __tree_.clear(); __tree_.value_comp() = __m.__tree_.value_comp(); __tree_.__copy_assign_alloc(__m.__tree_); insert(__m.begin(), __m.end()); } #endif return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY multimap(multimap&& __m) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) : __tree_(_VSTD::move(__m.__tree_)) { } multimap(multimap&& __m, const allocator_type& __a); _LIBCPP_INLINE_VISIBILITY multimap& operator=(multimap&& __m) _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) { __tree_ = _VSTD::move(__m.__tree_); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY multimap(initializer_list __il, const key_compare& __comp = key_compare()) : __tree_(__vc(__comp)) { insert(__il.begin(), __il.end()); } _LIBCPP_INLINE_VISIBILITY multimap(initializer_list __il, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__il.begin(), __il.end()); } #if _LIBCPP_STD_VER > 11 _LIBCPP_INLINE_VISIBILITY multimap(initializer_list __il, const allocator_type& __a) : multimap(__il, key_compare(), __a) {} #endif _LIBCPP_INLINE_VISIBILITY multimap& operator=(initializer_list __il) { __tree_.__assign_multi(__il.begin(), __il.end()); return *this; } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY explicit multimap(const allocator_type& __a) - : __tree_(__a) + : __tree_(typename __base::allocator_type(__a)) { } _LIBCPP_INLINE_VISIBILITY multimap(const multimap& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), __a) + : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) { insert(__m.begin(), __m.end()); } _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __tree_.begin();} _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __tree_.begin();} _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __tree_.end();} _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __tree_.end();} _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const _NOEXCEPT {return begin();} _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return end();} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const _NOEXCEPT {return rend();} _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __tree_.size() == 0;} _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __tree_.size();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __tree_.max_size();} _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} _LIBCPP_INLINE_VISIBILITY key_compare key_comp() const {return __tree_.value_comp().key_comp();} _LIBCPP_INLINE_VISIBILITY value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} #ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY iterator emplace(_Args&& ...__args) { return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...); } template _LIBCPP_INLINE_VISIBILITY iterator emplace_hint(const_iterator __p, _Args&& ...__args) { return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); } template ::value>::type> _LIBCPP_INLINE_VISIBILITY iterator insert(_Pp&& __p) {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));} template ::value>::type> _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __pos, _Pp&& __p) {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));} _LIBCPP_INLINE_VISIBILITY iterator insert(value_type&& __v) {return __tree_.__insert_multi(_VSTD::move(__v));} _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, value_type&& __v) {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));} #endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, const value_type& __v) {return __tree_.__insert_multi(__p.__i_, __v);} template _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __f, _InputIterator __l) { for (const_iterator __e = cend(); __f != __l; ++__f) __tree_.__insert_multi(__e.__i_, *__f); } #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY void insert(initializer_list __il) {insert(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY iterator erase(iterator __p) {return __tree_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);} _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __f, const_iterator __l) {return __tree_.erase(__f.__i_, __l.__i_);} _LIBCPP_INLINE_VISIBILITY void clear() {__tree_.clear();} _LIBCPP_INLINE_VISIBILITY void swap(multimap& __m) _NOEXCEPT_(__is_nothrow_swappable<__base>::value) {__tree_.swap(__m.__tree_);} _LIBCPP_INLINE_VISIBILITY iterator find(const key_type& __k) {return __tree_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __tree_.find(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type find(const _K2& __k) {return __tree_.find(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type find(const _K2& __k) const {return __tree_.find(__k);} #endif _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_multi(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type count(const _K2& __k) const {return __tree_.__count_multi(__k);} #endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) {return __tree_.lower_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const key_type& __k) const {return __tree_.lower_bound(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} #endif _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const key_type& __k) {return __tree_.upper_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const key_type& __k) const {return __tree_.upper_bound(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} #endif _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) {return __tree_.__equal_range_multi(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) const {return __tree_.__equal_range_multi(__k);} #if _LIBCPP_STD_VER > 11 template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} #endif private: typedef typename __base::__node __node; typedef typename __base::__node_allocator __node_allocator; typedef typename __base::__node_pointer __node_pointer; typedef __map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; }; #ifndef _LIBCPP_CXX03_LANG template multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) - : __tree_(_VSTD::move(__m.__tree_), __a) + : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a)) { if (__a != __m.get_allocator()) { const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_multi(__e.__i_, _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); } } #endif template inline _LIBCPP_INLINE_VISIBILITY bool operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); } template inline _LIBCPP_INLINE_VISIBILITY bool operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { return !(__x == __y); } template inline _LIBCPP_INLINE_VISIBILITY bool operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { return __y < __x; } template inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { return !(__x < __y); } template inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { return !(__y < __x); } template inline _LIBCPP_INLINE_VISIBILITY void swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, multimap<_Key, _Tp, _Compare, _Allocator>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MAP Index: vendor/libc++/dist/include/unordered_map =================================================================== --- vendor/libc++/dist/include/unordered_map (revision 304764) +++ vendor/libc++/dist/include/unordered_map (revision 304765) @@ -1,2071 +1,2071 @@ // -*- C++ -*- //===-------------------------- unordered_map -----------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_UNORDERED_MAP #define _LIBCPP_UNORDERED_MAP /* unordered_map synopsis #include namespace std { template , class Pred = equal_to, class Alloc = allocator>> class unordered_map { public: // types typedef Key key_type; typedef T mapped_type; typedef Hash hasher; typedef Pred key_equal; typedef Alloc allocator_type; typedef pair value_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename allocator_traits::pointer pointer; typedef typename allocator_traits::const_pointer const_pointer; typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::difference_type difference_type; typedef /unspecified/ iterator; typedef /unspecified/ const_iterator; typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; unordered_map() noexcept( is_nothrow_default_constructible::value && is_nothrow_default_constructible::value && is_nothrow_default_constructible::value); explicit unordered_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template unordered_map(InputIterator f, InputIterator l, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); explicit unordered_map(const allocator_type&); unordered_map(const unordered_map&); unordered_map(const unordered_map&, const Allocator&); unordered_map(unordered_map&&) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); unordered_map(unordered_map&&, const Allocator&); unordered_map(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_map(size_type n, const allocator_type& a) : unordered_map(n, hasher(), key_equal(), a) {} // C++14 unordered_map(size_type n, const hasher& hf, const allocator_type& a) : unordered_map(n, hf, key_equal(), a) {} // C++14 template unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_map(f, l, n, hasher(), key_equal(), a) {} // C++14 template unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14 unordered_map(initializer_list il, size_type n, const allocator_type& a) : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14 unordered_map(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(il, n, hf, key_equal(), a) {} // C++14 ~unordered_map(); unordered_map& operator=(const unordered_map&); unordered_map& operator=(unordered_map&&) noexcept( allocator_type::propagate_on_container_move_assignment::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); unordered_map& operator=(initializer_list); allocator_type get_allocator() const noexcept; bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; iterator begin() noexcept; iterator end() noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; template pair emplace(Args&&... args); template iterator emplace_hint(const_iterator position, Args&&... args); pair insert(const value_type& obj); template pair insert(P&& obj); iterator insert(const_iterator hint, const value_type& obj); template iterator insert(const_iterator hint, P&& obj); template void insert(InputIterator first, InputIterator last); void insert(initializer_list); template pair try_emplace(const key_type& k, Args&&... args); // C++17 template pair try_emplace(key_type&& k, Args&&... args); // C++17 template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 template pair insert_or_assign(const key_type& k, M&& obj); // C++17 template pair insert_or_assign(key_type&& k, M&& obj); // C++17 template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); iterator erase(const_iterator first, const_iterator last); void clear() noexcept; void swap(unordered_map&) noexcept( (!allocator_type::propagate_on_container_swap::value || __is_nothrow_swappable::value) && __is_nothrow_swappable::value && __is_nothrow_swappable::value); hasher hash_function() const; key_equal key_eq() const; iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; size_type bucket(const key_type& k) const; local_iterator begin(size_type n); local_iterator end(size_type n); const_local_iterator begin(size_type n) const; const_local_iterator end(size_type n) const; const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; float load_factor() const noexcept; float max_load_factor() const noexcept; void max_load_factor(float z); void rehash(size_type n); void reserve(size_type n); }; template void swap(unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); template bool operator==(const unordered_map& x, const unordered_map& y); template bool operator!=(const unordered_map& x, const unordered_map& y); template , class Pred = equal_to, class Alloc = allocator>> class unordered_multimap { public: // types typedef Key key_type; typedef T mapped_type; typedef Hash hasher; typedef Pred key_equal; typedef Alloc allocator_type; typedef pair value_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename allocator_traits::pointer pointer; typedef typename allocator_traits::const_pointer const_pointer; typedef typename allocator_traits::size_type size_type; typedef typename allocator_traits::difference_type difference_type; typedef /unspecified/ iterator; typedef /unspecified/ const_iterator; typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; unordered_multimap() noexcept( is_nothrow_default_constructible::value && is_nothrow_default_constructible::value && is_nothrow_default_constructible::value); explicit unordered_multimap(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template unordered_multimap(InputIterator f, InputIterator l, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); explicit unordered_multimap(const allocator_type&); unordered_multimap(const unordered_multimap&); unordered_multimap(const unordered_multimap&, const Allocator&); unordered_multimap(unordered_multimap&&) noexcept( is_nothrow_move_constructible::value && is_nothrow_move_constructible::value && is_nothrow_move_constructible::value); unordered_multimap(unordered_multimap&&, const Allocator&); unordered_multimap(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_multimap(size_type n, const allocator_type& a) : unordered_multimap(n, hasher(), key_equal(), a) {} // C++14 unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(n, hf, key_equal(), a) {} // C++14 template unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} // C++14 template unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14 unordered_multimap(initializer_list il, size_type n, const allocator_type& a) : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14 unordered_multimap(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(il, n, hf, key_equal(), a) {} // C++14 ~unordered_multimap(); unordered_multimap& operator=(const unordered_multimap&); unordered_multimap& operator=(unordered_multimap&&) noexcept( allocator_type::propagate_on_container_move_assignment::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value && is_nothrow_move_assignable::value); unordered_multimap& operator=(initializer_list); allocator_type get_allocator() const noexcept; bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; iterator begin() noexcept; iterator end() noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; template iterator emplace(Args&&... args); template iterator emplace_hint(const_iterator position, Args&&... args); iterator insert(const value_type& obj); template iterator insert(P&& obj); iterator insert(const_iterator hint, const value_type& obj); template iterator insert(const_iterator hint, P&& obj); template void insert(InputIterator first, InputIterator last); void insert(initializer_list); iterator erase(const_iterator position); iterator erase(iterator position); // C++14 size_type erase(const key_type& k); iterator erase(const_iterator first, const_iterator last); void clear() noexcept; void swap(unordered_multimap&) noexcept( (!allocator_type::propagate_on_container_swap::value || __is_nothrow_swappable::value) && __is_nothrow_swappable::value && __is_nothrow_swappable::value); hasher hash_function() const; key_equal key_eq() const; iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; size_type bucket_count() const noexcept; size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; size_type bucket(const key_type& k) const; local_iterator begin(size_type n); local_iterator end(size_type n); const_local_iterator begin(size_type n) const; const_local_iterator end(size_type n) const; const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; float load_factor() const noexcept; float max_load_factor() const noexcept; void max_load_factor(float z); void rehash(size_type n); void reserve(size_type n); }; template void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); template bool operator==(const unordered_multimap& x, const unordered_multimap& y); template bool operator!=(const unordered_multimap& x, const unordered_multimap& y); } // std */ #include <__config> #include <__hash_table> #include #include #include #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD template ::value && !__libcpp_is_final<_Hash>::value > class __unordered_map_hasher : private _Hash { public: _LIBCPP_INLINE_VISIBILITY __unordered_map_hasher() _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) : _Hash() {} _LIBCPP_INLINE_VISIBILITY __unordered_map_hasher(const _Hash& __h) _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value) : _Hash(__h) {} _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Cp& __x) const {return static_cast(*this)(__x.__cc.first);} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return static_cast(*this)(__x);} void swap(__unordered_map_hasher&__y) _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value) { using _VSTD::swap; swap(static_cast(*this), static_cast(__y)); } }; template class __unordered_map_hasher<_Key, _Cp, _Hash, false> { _Hash __hash_; public: _LIBCPP_INLINE_VISIBILITY __unordered_map_hasher() _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) : __hash_() {} _LIBCPP_INLINE_VISIBILITY __unordered_map_hasher(const _Hash& __h) _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value) : __hash_(__h) {} _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const _NOEXCEPT {return __hash_;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Cp& __x) const {return __hash_(__x.__cc.first);} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return __hash_(__x);} void swap(__unordered_map_hasher&__y) _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value) { using _VSTD::swap; swap(__hash_, __y.__hash_); } }; template inline _LIBCPP_INLINE_VISIBILITY void swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x, __unordered_map_hasher<_Key, _Cp, _Hash, __b>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } template ::value && !__libcpp_is_final<_Pred>::value > class __unordered_map_equal : private _Pred { public: _LIBCPP_INLINE_VISIBILITY __unordered_map_equal() _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) : _Pred() {} _LIBCPP_INLINE_VISIBILITY __unordered_map_equal(const _Pred& __p) _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) : _Pred(__p) {} _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Cp& __y) const {return static_cast(*this)(__x.__cc.first, __y.__cc.first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Key& __y) const {return static_cast(*this)(__x.__cc.first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const {return static_cast(*this)(__x, __y.__cc.first);} void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { using _VSTD::swap; swap(static_cast(*this), static_cast(__y)); } }; template class __unordered_map_equal<_Key, _Cp, _Pred, false> { _Pred __pred_; public: _LIBCPP_INLINE_VISIBILITY __unordered_map_equal() _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) : __pred_() {} _LIBCPP_INLINE_VISIBILITY __unordered_map_equal(const _Pred& __p) _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) : __pred_(__p) {} _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const _NOEXCEPT {return __pred_;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Cp& __y) const {return __pred_(__x.__cc.first, __y.__cc.first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Key& __y) const {return __pred_(__x.__cc.first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const {return __pred_(__x, __y.__cc.first);} void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { using _VSTD::swap; swap(__pred_, __y.__pred_); } }; template inline _LIBCPP_INLINE_VISIBILITY void swap(__unordered_map_equal<_Key, _Cp, _Pred, __b>& __x, __unordered_map_equal<_Key, _Cp, _Pred, __b>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } template class __hash_map_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits __alloc_traits; public: typedef typename __alloc_traits::pointer pointer; private: allocator_type& __na_; __hash_map_node_destructor& operator=(const __hash_map_node_destructor&); public: bool __first_constructed; bool __second_constructed; _LIBCPP_INLINE_VISIBILITY explicit __hash_map_node_destructor(allocator_type& __na) _NOEXCEPT : __na_(__na), __first_constructed(false), __second_constructed(false) {} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY __hash_map_node_destructor(__hash_node_destructor&& __x) _NOEXCEPT : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) { __x.__value_constructed = false; } #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY __hash_map_node_destructor(const __hash_node_destructor& __x) : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) { const_cast(__x.__value_constructed) = false; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void operator()(pointer __p) _NOEXCEPT { if (__second_constructed) __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second)); if (__first_constructed) __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } }; #ifndef _LIBCPP_CXX03_LANG template union __hash_value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; typedef pair __nc_value_type; value_type __cc; __nc_value_type __nc; _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(const __hash_value_type& __v) {__nc = __v.__cc; return *this;} _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(__hash_value_type&& __v) {__nc = _VSTD::move(__v.__nc); return *this;} template ::value >::type > _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(_ValueTp&& __v) { __nc = _VSTD::forward<_ValueTp>(__v); return *this; } private: __hash_value_type(const __hash_value_type& __v) = delete; __hash_value_type(__hash_value_type&& __v) = delete; template explicit __hash_value_type(_Args&& ...__args) = delete; ~__hash_value_type() = delete; }; #else template struct __hash_value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; value_type __cc; private: ~__hash_value_type(); }; #endif template class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator { _HashIterator __i_; typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; public: typedef forward_iterator_tag iterator_category; typedef typename _NodeTypes::__map_value_type value_type; typedef typename _NodeTypes::difference_type difference_type; typedef value_type& reference; typedef typename _NodeTypes::__map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __i_->__cc;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return pointer_traits::pointer_to(__i_->__cc);} _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;} _LIBCPP_INLINE_VISIBILITY __hash_map_iterator operator++(int) { __hash_map_iterator __t(*this); ++(*this); return __t; } friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) {return __x.__i_ == __y.__i_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) {return __x.__i_ != __y.__i_;} template friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; template friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; template friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; }; template class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator { _HashIterator __i_; typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; public: typedef forward_iterator_tag iterator_category; typedef typename _NodeTypes::__map_value_type value_type; typedef typename _NodeTypes::difference_type difference_type; typedef const value_type& reference; typedef typename _NodeTypes::__const_map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator( __hash_map_iterator __i) _NOEXCEPT : __i_(__i.__i_) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __i_->__cc;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return pointer_traits::pointer_to(__i_->__cc);} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator& operator++() {++__i_; return *this;} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator operator++(int) { __hash_map_const_iterator __t(*this); ++(*this); return __t; } friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) {return __x.__i_ == __y.__i_;} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) {return __x.__i_ != __y.__i_;} template friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; template friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; template friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; }; template , class _Pred = equal_to<_Key>, class _Alloc = allocator > > class _LIBCPP_TYPE_VIS_ONLY unordered_map { public: // types typedef _Key key_type; typedef _Tp mapped_type; typedef _Hash hasher; typedef _Pred key_equal; typedef _Alloc allocator_type; typedef pair value_type; typedef pair __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), "Invalid allocator::value_type"); private: typedef __hash_value_type __value_type; typedef __unordered_map_hasher __hasher; typedef __unordered_map_equal __key_equal; typedef typename __rebind_alloc_helper, __value_type>::type __allocator_type; typedef __hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table; __table __table_; typedef typename __table::_NodeTypes _NodeTypes; typedef typename __table::__node_pointer __node_pointer; typedef typename __table::__node_const_pointer __node_const_pointer; typedef typename __table::__node_traits __node_traits; typedef typename __table::__node_allocator __node_allocator; typedef typename __table::__node __node; typedef __hash_map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; typedef allocator_traits __alloc_traits; static_assert((is_same::value), ""); static_assert((is_same::value), ""); public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __table::size_type size_type; typedef typename __table::difference_type difference_type; typedef __hash_map_iterator iterator; typedef __hash_map_const_iterator const_iterator; typedef __hash_map_iterator local_iterator; typedef __hash_map_const_iterator const_local_iterator; _LIBCPP_INLINE_VISIBILITY unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif } explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_map(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); template unordered_map(_InputIterator __first, _InputIterator __last); template unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); template unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); _LIBCPP_INLINE_VISIBILITY explicit unordered_map(const allocator_type& __a); unordered_map(const unordered_map& __u); unordered_map(const unordered_map& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY unordered_map(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_map(unordered_map&& __u, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS unordered_map(initializer_list __il); unordered_map(initializer_list __il, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_map(initializer_list __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #if _LIBCPP_STD_VER > 11 _LIBCPP_INLINE_VISIBILITY unordered_map(size_type __n, const allocator_type& __a) : unordered_map(__n, hasher(), key_equal(), __a) {} _LIBCPP_INLINE_VISIBILITY unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__n, __hf, key_equal(), __a) {} template _LIBCPP_INLINE_VISIBILITY unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {} template _LIBCPP_INLINE_VISIBILITY unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {} _LIBCPP_INLINE_VISIBILITY unordered_map(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_map(__il, __n, hasher(), key_equal(), __a) {} _LIBCPP_INLINE_VISIBILITY unordered_map(initializer_list __il, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__il, __n, __hf, key_equal(), __a) {} #endif // ~unordered_map() = default; _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(const unordered_map& __u) { #ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else if (this != &__u) { __table_.clear(); __table_.hash_function() = __u.__table_.hash_function(); __table_.key_eq() = __u.__table_.key_eq(); __table_.max_load_factor() = __u.__table_.max_load_factor(); __table_.__copy_assign_alloc(__u.__table_); insert(__u.begin(), __u.end()); } #endif return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(initializer_list __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __table_.size() == 0;} _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __table_.size();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY pair insert(const value_type& __x) {return __table_.__insert_unique(__x);} iterator insert(const_iterator __p, const value_type& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_map"); #endif return insert(__x).first; } template _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY void insert(initializer_list __il) {insert(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair insert(value_type&& __x) {return __table_.__insert_unique(_VSTD::move(__x));} iterator insert(const_iterator __p, value_type&& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_map"); #endif return __table_.__insert_unique(_VSTD::move(__x)).first; } template ::value>::type> _LIBCPP_INLINE_VISIBILITY pair insert(_Pp&& __x) {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));} template ::value>::type> _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, _Pp&& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_map"); #endif return insert(_VSTD::forward<_Pp>(__x)).first; } template _LIBCPP_INLINE_VISIBILITY pair emplace(_Args&&... __args) { return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...); } template _LIBCPP_INLINE_VISIBILITY iterator emplace_hint(const_iterator __p, _Args&&... __args) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_map"); #endif return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; } #endif // _LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER > 14 template _LIBCPP_INLINE_VISIBILITY pair try_emplace(const key_type& __k, _Args&&... __args) { return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template _LIBCPP_INLINE_VISIBILITY pair try_emplace(key_type&& __k, _Args&&... __args) { return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" " referring to this unordered_map"); #endif return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } template _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" " referring to this unordered_map"); #endif return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } template _LIBCPP_INLINE_VISIBILITY pair insert_or_assign(const key_type& __k, _Vp&& __v) { pair __res = __table_.__emplace_unique_key_args(__k, __k, _VSTD::forward<_Vp>(__v)); if (!__res.second) { __res.first->second = _VSTD::forward<_Vp>(__v); } return __res; } template _LIBCPP_INLINE_VISIBILITY pair insert_or_assign(key_type&& __k, _Vp&& __v) { pair __res = __table_.__emplace_unique_key_args(__k, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); if (!__res.second) { __res.first->second = _VSTD::forward<_Vp>(__v); } return __res; } template _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) { return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first; } template _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) { return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; } #endif _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY iterator erase(iterator __p) {return __table_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __first, const_iterator __last) {return __table_.erase(__first.__i_, __last.__i_);} _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__table_.clear();} _LIBCPP_INLINE_VISIBILITY void swap(unordered_map& __u) _NOEXCEPT_(__is_nothrow_swappable<__table>::value) {__table_.swap(__u.__table_);} _LIBCPP_INLINE_VISIBILITY hasher hash_function() const {return __table_.hash_function().hash_function();} _LIBCPP_INLINE_VISIBILITY key_equal key_eq() const {return __table_.key_eq().key_eq();} _LIBCPP_INLINE_VISIBILITY iterator find(const key_type& __k) {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) {return __table_.__equal_range_unique(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) const {return __table_.__equal_range_unique(__k);} mapped_type& operator[](const key_type& __k); #ifndef _LIBCPP_CXX03_LANG mapped_type& operator[](key_type&& __k); #endif mapped_type& at(const key_type& __k); const mapped_type& at(const key_type& __k) const; _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} _LIBCPP_INLINE_VISIBILITY size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} _LIBCPP_INLINE_VISIBILITY size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);} _LIBCPP_INLINE_VISIBILITY size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} _LIBCPP_INLINE_VISIBILITY local_iterator begin(size_type __n) {return __table_.begin(__n);} _LIBCPP_INLINE_VISIBILITY local_iterator end(size_type __n) {return __table_.end(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator end(size_type __n) const {return __table_.cend(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT {return __table_.load_factor();} _LIBCPP_INLINE_VISIBILITY float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} _LIBCPP_INLINE_VISIBILITY void rehash(size_type __n) {__table_.rehash(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.reserve(__n);} #if _LIBCPP_DEBUG_LEVEL >= 2 bool __dereferenceable(const const_iterator* __i) const {return __table_.__dereferenceable(&__i->__i_);} bool __decrementable(const const_iterator* __i) const {return __table_.__decrementable(&__i->__i_);} bool __addable(const const_iterator* __i, ptrdiff_t __n) const {return __table_.__addable(&__i->__i_, __n);} bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const {return __table_.__addable(&__i->__i_, __n);} #endif // _LIBCPP_DEBUG_LEVEL >= 2 private: #ifdef _LIBCPP_CXX03_LANG __node_holder __construct_node_with_key(const key_type& __k); #endif }; template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); } template inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) - : __table_(__a) + : __table_(typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif } template template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif insert(__first, __last); } template template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__first, __last); } template template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__first, __last); } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u) : __table_(__u.__table_) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) + : __table_(__u.__table_, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); __get_db()->swap(this, &__u); #endif } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) + : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif if (__a != __u.get_allocator()) { iterator __i = __u.begin(); while (__u.size() != 0) { __table_.__emplace_unique(_VSTD::move( __u.__table_.remove((__i++).__i_)->__value_.__nc)); } } #if _LIBCPP_DEBUG_LEVEL >= 2 else __get_db()->swap(this, &__u); #endif } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list __il) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif insert(__il.begin(), __il.end()); } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list __il, size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) { __table_ = _VSTD::move(__u.__table_); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( initializer_list __il) { __table_.__assign_unique(__il.begin(), __il.end()); return *this; } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifdef _LIBCPP_CXX03_LANG template typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k) { __node_allocator& __na = __table_.__node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k); __h.get_deleter().__first_constructed = true; __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); __h.get_deleter().__second_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } #endif template template inline void unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) __table_.__insert_unique(*__first); } #ifdef _LIBCPP_CXX03_LANG template _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) { iterator __i = find(__k); if (__i != end()) return __i->second; __node_holder __h = __construct_node_with_key(__k); pair __r = __table_.__node_insert_unique(__h.get()); __h.release(); return __r.first->second; } #else template _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) { return __table_.__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple()).first->__cc.second; } template _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k) { return __table_.__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple()).first->__cc.second; } #endif // !_LIBCPP_CXX03_MODE template _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) { iterator __i = find(__k); #ifndef _LIBCPP_NO_EXCEPTIONS if (__i == end()) throw out_of_range("unordered_map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS return __i->second; } template const _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const { const_iterator __i = find(__k); #ifndef _LIBCPP_NO_EXCEPTIONS if (__i == end()) throw out_of_range("unordered_map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS return __i->second; } template inline _LIBCPP_INLINE_VISIBILITY void swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } template bool operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { if (__x.size() != __y.size()) return false; typedef typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator const_iterator; for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); __i != __ex; ++__i) { const_iterator __j = __y.find(__i->first); if (__j == __ey || !(*__i == *__j)) return false; } return true; } template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } template , class _Pred = equal_to<_Key>, class _Alloc = allocator > > class _LIBCPP_TYPE_VIS_ONLY unordered_multimap { public: // types typedef _Key key_type; typedef _Tp mapped_type; typedef _Hash hasher; typedef _Pred key_equal; typedef _Alloc allocator_type; typedef pair value_type; typedef pair __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), "Invalid allocator::value_type"); private: typedef __hash_value_type __value_type; typedef __unordered_map_hasher __hasher; typedef __unordered_map_equal __key_equal; typedef typename __rebind_alloc_helper, __value_type>::type __allocator_type; typedef __hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table; __table __table_; typedef typename __table::_NodeTypes _NodeTypes; typedef typename __table::__node_traits __node_traits; typedef typename __table::__node_allocator __node_allocator; typedef typename __table::__node __node; typedef __hash_map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; typedef allocator_traits __alloc_traits; static_assert((is_same::value), "Allocator uses different size_type for different types"); public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __table::size_type size_type; typedef typename __table::difference_type difference_type; typedef __hash_map_iterator iterator; typedef __hash_map_const_iterator const_iterator; typedef __hash_map_iterator local_iterator; typedef __hash_map_const_iterator const_local_iterator; _LIBCPP_INLINE_VISIBILITY unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif } explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); template unordered_multimap(_InputIterator __first, _InputIterator __last); template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); _LIBCPP_INLINE_VISIBILITY explicit unordered_multimap(const allocator_type& __a); unordered_multimap(const unordered_multimap& __u); unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY unordered_multimap(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS unordered_multimap(initializer_list __il); unordered_multimap(initializer_list __il, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multimap(initializer_list __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #if _LIBCPP_STD_VER > 11 _LIBCPP_INLINE_VISIBILITY unordered_multimap(size_type __n, const allocator_type& __a) : unordered_multimap(__n, hasher(), key_equal(), __a) {} _LIBCPP_INLINE_VISIBILITY unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__n, __hf, key_equal(), __a) {} template _LIBCPP_INLINE_VISIBILITY unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) {} template _LIBCPP_INLINE_VISIBILITY unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {} _LIBCPP_INLINE_VISIBILITY unordered_multimap(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {} _LIBCPP_INLINE_VISIBILITY unordered_multimap(initializer_list __il, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__il, __n, __hf, key_equal(), __a) {} #endif // ~unordered_multimap() = default; _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(const unordered_multimap& __u) { #ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else if (this != &__u) { __table_.clear(); __table_.hash_function() = __u.__table_.hash_function(); __table_.key_eq() = __u.__table_.key_eq(); __table_.max_load_factor() = __u.__table_.max_load_factor(); __table_.__copy_assign_alloc(__u.__table_); insert(__u.begin(), __u.end()); } #endif return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(initializer_list __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __table_.size() == 0;} _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT {return __table_.size();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, const value_type& __x) {return __table_.__insert_multi(__p.__i_, __x);} template _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY void insert(initializer_list __il) {insert(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));} _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, value_type&& __x) {return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));} template ::value>::type> _LIBCPP_INLINE_VISIBILITY iterator insert(_Pp&& __x) {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));} template ::value>::type> _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, _Pp&& __x) {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} template iterator emplace(_Args&&... __args) { return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...); } template iterator emplace_hint(const_iterator __p, _Args&&... __args) { return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); } #endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY iterator erase(iterator __p) {return __table_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);} _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __first, const_iterator __last) {return __table_.erase(__first.__i_, __last.__i_);} _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__table_.clear();} _LIBCPP_INLINE_VISIBILITY void swap(unordered_multimap& __u) _NOEXCEPT_(__is_nothrow_swappable<__table>::value) {__table_.swap(__u.__table_);} _LIBCPP_INLINE_VISIBILITY hasher hash_function() const {return __table_.hash_function().hash_function();} _LIBCPP_INLINE_VISIBILITY key_equal key_eq() const {return __table_.key_eq().key_eq();} _LIBCPP_INLINE_VISIBILITY iterator find(const key_type& __k) {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __table_.find(__k);} _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) {return __table_.__equal_range_multi(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) const {return __table_.__equal_range_multi(__k);} _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} _LIBCPP_INLINE_VISIBILITY size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} _LIBCPP_INLINE_VISIBILITY size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);} _LIBCPP_INLINE_VISIBILITY size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} _LIBCPP_INLINE_VISIBILITY local_iterator begin(size_type __n) {return __table_.begin(__n);} _LIBCPP_INLINE_VISIBILITY local_iterator end(size_type __n) {return __table_.end(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator end(size_type __n) const {return __table_.cend(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} _LIBCPP_INLINE_VISIBILITY const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT {return __table_.load_factor();} _LIBCPP_INLINE_VISIBILITY float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} _LIBCPP_INLINE_VISIBILITY void rehash(size_type __n) {__table_.rehash(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.reserve(__n);} #if _LIBCPP_DEBUG_LEVEL >= 2 bool __dereferenceable(const const_iterator* __i) const {return __table_.__dereferenceable(&__i->__i_);} bool __decrementable(const const_iterator* __i) const {return __table_.__decrementable(&__i->__i_);} bool __addable(const const_iterator* __i, ptrdiff_t __n) const {return __table_.__addable(&__i->__i_, __n);} bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const {return __table_.__addable(&__i->__i_, __n);} #endif // _LIBCPP_DEBUG_LEVEL >= 2 }; template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); } template template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif insert(__first, __last); } template template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__first, __last); } template template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__first, __last); } template inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) - : __table_(__a) + : __table_(typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u) : __table_(__u.__table_) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) + : __table_(__u.__table_, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); __get_db()->swap(this, &__u); #endif } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) + : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif if (__a != __u.get_allocator()) { iterator __i = __u.begin(); while (__u.size() != 0) { __table_.__insert_multi( _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_.__nc) ); } } #if _LIBCPP_DEBUG_LEVEL >= 2 else __get_db()->swap(this, &__u); #endif } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list __il) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif insert(__il.begin(), __il.end()); } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list __il, size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) { __table_ = _VSTD::move(__u.__table_); return *this; } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( initializer_list __il) { __table_.__assign_multi(__il.begin(), __il.end()); return *this; } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template template inline void unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) __table_.__insert_multi(*__first); } template inline _LIBCPP_INLINE_VISIBILITY void swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } template bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { if (__x.size() != __y.size()) return false; typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator const_iterator; typedef pair _EqRng; for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) { _EqRng __xeq = __x.equal_range(__i->first); _EqRng __yeq = __y.equal_range(__i->first); if (_VSTD::distance(__xeq.first, __xeq.second) != _VSTD::distance(__yeq.first, __yeq.second) || !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) return false; __i = __xeq.second; } return true; } template inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_UNORDERED_MAP Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/alloc.pass.cpp (revision 304765) @@ -1,42 +1,50 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // explicit map(const allocator_type& a); #include #include #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::less C; typedef test_allocator > A; std::map m(A(5)); assert(m.empty()); assert(m.begin() == m.end()); assert(m.get_allocator() == A(5)); } #if TEST_STD_VER >= 11 { typedef std::less C; typedef min_allocator > A; std::map m(A{}); assert(m.empty()); assert(m.begin() == m.end()); assert(m.get_allocator() == A()); } + { + typedef std::less C; + typedef explicit_allocator > A; + std::map m(A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.get_allocator() == A()); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp (revision 304765) @@ -1,45 +1,54 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // map(const key_compare& comp, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef test_compare > C; typedef test_allocator > A; std::map m(C(4), A(5)); assert(m.empty()); assert(m.begin() == m.end()); assert(m.key_comp() == C(4)); assert(m.get_allocator() == A(5)); } #if TEST_STD_VER >= 11 { typedef test_compare > C; typedef min_allocator > A; std::map m(C(4), A()); assert(m.empty()); assert(m.begin() == m.end()); assert(m.key_comp() == C(4)); assert(m.get_allocator() == A()); } + { + typedef test_compare > C; + typedef explicit_allocator > A; + std::map m(C(4), A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.key_comp() == C(4)); + assert(m.get_allocator() == A{}); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp (revision 304765) @@ -1,95 +1,129 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // map(const map& m, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef test_allocator A; std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(7)); std::map m(mo, A(3)); assert(m.get_allocator() == A(3)); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(mo.get_allocator() == A(7)); assert(mo.key_comp() == C(5)); assert(mo.size() == 3); assert(distance(mo.begin(), mo.end()) == 3); assert(*mo.begin() == V(1, 1)); assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } #if TEST_STD_VER >= 11 { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef min_allocator A; std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); std::map m(mo, A()); assert(m.get_allocator() == A()); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(mo.get_allocator() == A()); assert(mo.key_comp() == C(5)); assert(mo.size() == 3); assert(distance(mo.begin(), mo.end()) == 3); assert(*mo.begin() == V(1, 1)); assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } + { + typedef std::pair V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + typedef test_compare > C; + typedef explicit_allocator A; + std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A{}); + std::map m(mo, A{}); + assert(m.get_allocator() == A()); + assert(m.key_comp() == C(5)); + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + + assert(mo.get_allocator() == A()); + assert(mo.key_comp() == C(5)); + assert(mo.size() == 3); + assert(distance(mo.begin(), mo.end()) == 3); + assert(*mo.begin() == V(1, 1)); + assert(*next(mo.begin()) == V(2, 1)); + assert(*next(mo.begin(), 2) == V(3, 1)); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp (revision 304765) @@ -1,182 +1,340 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // map& operator=(const map& m); #include #include +#include +#include +#include + #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" +#if TEST_STD_VER >= 11 +std::vector ca_allocs; +std::vector ca_deallocs; + +template +class counting_allocatorT { +public: + typedef T value_type; + int foo{0}; + counting_allocatorT(int f) noexcept : foo(f) {} + + using propagate_on_container_copy_assignment = std::true_type; + template counting_allocatorT(const counting_allocatorT& other) noexcept {foo = other.foo;} + template bool operator==(const counting_allocatorT& other) const noexcept { return foo == other.foo; } + template bool operator!=(const counting_allocatorT& other) const noexcept { return foo != other.foo; } + + T * allocate(const size_t n) const { + ca_allocs.push_back(foo); + void * const pv = ::malloc(n * sizeof(T)); + return static_cast(pv); + } + void deallocate(T * const p, size_t) const noexcept { + ca_deallocs.push_back(foo); + free(p); + } +}; + +template +class counting_allocatorF { +public: + typedef T value_type; + int foo{0}; + counting_allocatorF(int f) noexcept : foo(f) {} + + using propagate_on_container_copy_assignment = std::false_type; + template counting_allocatorF(const counting_allocatorF& other) noexcept {foo = other.foo;} + template bool operator==(const counting_allocatorF& other) const noexcept { return foo == other.foo; } + template bool operator!=(const counting_allocatorF& other) const noexcept { return foo != other.foo; } + + T * allocate(const size_t n) const { + ca_allocs.push_back(foo); + void * const pv = ::malloc(n * sizeof(T)); + return static_cast(pv); + } + void deallocate(T * const p, size_t) const noexcept { + ca_deallocs.push_back(foo); + free(p); + } +}; + +bool balanced_allocs() { + std::vector temp1, temp2; + + std::cout << "Allocations = " << ca_allocs.size() << ", deallocatons = " << ca_deallocs.size() << std::endl; + if (ca_allocs.size() != ca_deallocs.size()) + return false; + + temp1 = ca_allocs; + std::sort(temp1.begin(), temp1.end()); + temp2.clear(); + std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter>(temp2)); + std::cout << "There were " << temp2.size() << " different allocators\n"; + + for (std::vector::const_iterator it = temp2.begin(); it != temp2.end(); ++it ) { + std::cout << *it << ": " << std::count(ca_allocs.begin(), ca_allocs.end(), *it) << " vs " << std::count(ca_deallocs.begin(), ca_deallocs.end(), *it) << std::endl; + if ( std::count(ca_allocs.begin(), ca_allocs.end(), *it) != std::count(ca_deallocs.begin(), ca_deallocs.end(), *it)) + return false; + } + + temp1 = ca_allocs; + std::sort(temp1.begin(), temp1.end()); + temp2.clear(); + std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter>(temp2)); + std::cout << "There were " << temp2.size() << " different (de)allocators\n"; + for (std::vector::const_iterator it = ca_deallocs.begin(); it != ca_deallocs.end(); ++it ) { + std::cout << *it << ": " << std::count(ca_allocs.begin(), ca_allocs.end(), *it) << " vs " << std::count(ca_deallocs.begin(), ca_deallocs.end(), *it) << std::endl; + if ( std::count(ca_allocs.begin(), ca_allocs.end(), *it) != std::count(ca_deallocs.begin(), ca_deallocs.end(), *it)) + return false; + } + + return true; + } +#endif + int main() { { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2) }; typedef test_compare > C; typedef test_allocator A; std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2)); std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7)); m = mo; assert(m.get_allocator() == A(7)); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(mo.get_allocator() == A(2)); assert(mo.key_comp() == C(5)); assert(mo.size() == 3); assert(distance(mo.begin(), mo.end()) == 3); assert(*mo.begin() == V(1, 1)); assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } { typedef std::pair V; const V ar[] = { V(1, 1), V(2, 1), V(3, 1), }; std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])); std::map *p = &m; m = *p; assert(m.size() == 3); assert(std::equal(m.begin(), m.end(), ar)); } { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2) }; typedef test_compare > C; typedef other_allocator A; std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2)); std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7)); m = mo; assert(m.get_allocator() == A(2)); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(mo.get_allocator() == A(2)); assert(mo.key_comp() == C(5)); assert(mo.size() == 3); assert(distance(mo.begin(), mo.end()) == 3); assert(*mo.begin() == V(1, 1)); assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } #if TEST_STD_VER >= 11 { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2) }; typedef test_compare > C; typedef min_allocator A; std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A()); m = mo; assert(m.get_allocator() == A()); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(mo.get_allocator() == A()); assert(mo.key_comp() == C(5)); assert(mo.size() == 3); assert(distance(mo.begin(), mo.end()) == 3); assert(*mo.begin() == V(1, 1)); assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2) }; typedef test_compare > C; typedef min_allocator A; std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A()); m = mo; assert(m.get_allocator() == A()); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(mo.get_allocator() == A()); assert(mo.key_comp() == C(5)); assert(mo.size() == 3); assert(distance(mo.begin(), mo.end()) == 3); assert(*mo.begin() == V(1, 1)); assert(*next(mo.begin()) == V(2, 1)); assert(*next(mo.begin(), 2) == V(3, 1)); } + + assert(balanced_allocs()); + { + typedef std::pair V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2) + }; + typedef test_compare > C; + typedef counting_allocatorT A; + std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(1)); + std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(2)); + m = mo; + assert(m.key_comp() == C(5)); + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + + assert(mo.key_comp() == C(5)); + assert(mo.size() == 3); + assert(distance(mo.begin(), mo.end()) == 3); + assert(*mo.begin() == V(1, 1)); + assert(*next(mo.begin()) == V(2, 1)); + assert(*next(mo.begin(), 2) == V(3, 1)); + } + assert(balanced_allocs()); + { + typedef std::pair V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2) + }; + typedef test_compare > C; + typedef counting_allocatorF A; + std::map mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(100)); + std::map m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(200)); + m = mo; + assert(m.key_comp() == C(5)); + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + + assert(mo.key_comp() == C(5)); + assert(mo.size() == 3); + assert(distance(mo.begin(), mo.end()) == 3); + assert(*mo.begin() == V(1, 1)); + assert(*next(mo.begin()) == V(2, 1)); + assert(*next(mo.begin(), 2) == V(3, 1)); + } + assert(balanced_allocs()); #endif } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/default.pass.cpp (revision 304765) @@ -1,40 +1,54 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // map(); #include #include #include "min_allocator.h" int main() { { std::map m; assert(m.empty()); assert(m.begin() == m.end()); } #if TEST_STD_VER >= 11 { std::map, min_allocator>> m; assert(m.empty()); assert(m.begin() == m.end()); } { + typedef explicit_allocator> A; + { + std::map, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::map, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + { std::map m = {}; assert(m.empty()); assert(m.begin() == m.end()); } #endif } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp (revision 304765) @@ -1,100 +1,124 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // map(initializer_list il, const key_compare& comp, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { typedef std::pair V; typedef test_compare > C; typedef test_allocator > A; std::map m({ {1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2} }, C(3), A(6)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(m.key_comp() == C(3)); assert(m.get_allocator() == A(6)); } #if TEST_STD_VER >= 11 { typedef std::pair V; typedef test_compare > C; typedef min_allocator > A; std::map m({ {1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2} }, C(3), A()); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(m.key_comp() == C(3)); assert(m.get_allocator() == A()); } -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::pair V; typedef min_allocator A; typedef test_compare > C; typedef std::map M; A a; M m ({ {1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2} }, a); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(m.get_allocator() == a); } #endif + { + typedef std::pair V; + typedef explicit_allocator A; + typedef test_compare > C; + A a; + std::map m({ + {1, 1}, + {1, 1.5}, + {1, 2}, + {2, 1}, + {2, 1.5}, + {2, 2}, + {3, 1}, + {3, 1.5}, + {3, 2} + }, C(3), a); + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + assert(m.key_comp() == C(3)); + assert(m.get_allocator() == a); + } #endif #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp (revision 304765) @@ -1,108 +1,124 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // template // map(InputIterator first, InputIterator last, // const key_compare& comp, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef test_allocator A; std::map m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(7)); assert(m.get_allocator() == A(7)); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } #if TEST_STD_VER >= 11 { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef min_allocator A; std::map m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); assert(m.get_allocator() == A()); assert(m.key_comp() == C(5)); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); } #if _LIBCPP_STD_VER > 11 { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; + { typedef std::pair V; typedef min_allocator A; typedef test_compare > C; A a; std::map m(ar, ar+sizeof(ar)/sizeof(ar[0]), a ); assert(m.size() == 3); assert(distance(m.begin(), m.end()) == 3); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(2, 1)); assert(*next(m.begin(), 2) == V(3, 1)); assert(m.get_allocator() == a); + } + { + typedef std::pair V; + typedef explicit_allocator A; + typedef test_compare > C; + A a; + std::map m(ar, ar+sizeof(ar)/sizeof(ar[0]), a ); + + assert(m.size() == 3); + assert(distance(m.begin(), m.end()) == 3); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(2, 1)); + assert(*next(m.begin(), 2) == V(3, 1)); + assert(m.get_allocator() == a); + } } #endif #endif } Index: vendor/libc++/dist/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp (revision 304765) @@ -1,234 +1,273 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class map // map(map&& m, const allocator_type& a); #include #include #include "MoveOnly.h" #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" #include "Counter.h" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef test_allocator A; typedef std::map M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A(7)); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A(7)); M m3(std::move(m1), A(7)); assert(m3 == m2); assert(m3.get_allocator() == A(7)); assert(m3.key_comp() == C(5)); assert(m1.empty()); } { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef test_allocator A; typedef std::map M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A(7)); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A(7)); M m3(std::move(m1), A(5)); assert(m3 == m2); assert(m3.get_allocator() == A(5)); assert(m3.key_comp() == C(5)); assert(m1.empty()); } { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef other_allocator A; typedef std::map M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A(7)); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A(7)); M m3(std::move(m1), A(5)); assert(m3 == m2); assert(m3.get_allocator() == A(5)); assert(m3.key_comp() == C(5)); assert(m1.empty()); } { typedef Counter T; typedef std::pair V; typedef std::pair VC; typedef test_allocator A; typedef std::less C; typedef std::map M; typedef V* I; Counter_base::gConstructed = 0; { V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; const size_t num = sizeof(a1)/sizeof(a1[0]); assert(Counter_base::gConstructed == num); M m1(I(a1), I(a1+num), C(), A()); assert(Counter_base::gConstructed == num+3); M m2(m1); assert(m2 == m1); assert(Counter_base::gConstructed == num+6); M m3(std::move(m1), A()); assert(m3 == m2); assert(m1.empty()); assert(Counter_base::gConstructed == num+6); { M m4(std::move(m2), A(5)); assert(Counter_base::gConstructed == num+6); assert(m4 == m3); assert(m2.empty()); } assert(Counter_base::gConstructed == num+3); } assert(Counter_base::gConstructed == 0); } #if TEST_STD_VER >= 11 { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef min_allocator A; typedef std::map M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A()); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A()); M m3(std::move(m1), A()); assert(m3 == m2); assert(m3.get_allocator() == A()); assert(m3.key_comp() == C(5)); assert(m1.empty()); } + { + typedef std::pair V; + typedef std::pair VC; + typedef test_compare > C; + typedef explicit_allocator A; + typedef std::map M; + typedef std::move_iterator I; + V a1[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A{}); + V a2[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A{}); + M m3(std::move(m1), A{}); + assert(m3 == m2); + assert(m3.get_allocator() == A{}); + assert(m3.key_comp() == C(5)); + assert(m1.empty()); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/alloc.pass.cpp (revision 304765) @@ -1,42 +1,50 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // explicit multimap(const allocator_type& a); #include #include #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::less C; typedef test_allocator > A; std::multimap m(A(5)); assert(m.empty()); assert(m.begin() == m.end()); assert(m.get_allocator() == A(5)); } #if TEST_STD_VER >= 11 { typedef std::less C; typedef min_allocator > A; std::multimap m(A{}); assert(m.empty()); assert(m.begin() == m.end()); assert(m.get_allocator() == A()); } + { + typedef std::less C; + typedef explicit_allocator > A; + std::multimap m(A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.get_allocator() == A{}); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp (revision 304765) @@ -1,45 +1,54 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // multimap(const key_compare& comp, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef test_compare > C; typedef test_allocator > A; std::multimap m(C(4), A(5)); assert(m.empty()); assert(m.begin() == m.end()); assert(m.key_comp() == C(4)); assert(m.get_allocator() == A(5)); } #if TEST_STD_VER >= 11 { typedef test_compare > C; typedef min_allocator > A; std::multimap m(C(4), A()); assert(m.empty()); assert(m.begin() == m.end()); assert(m.key_comp() == C(4)); assert(m.get_allocator() == A()); } + { + typedef test_compare > C; + typedef explicit_allocator > A; + std::multimap m(C(4), A{}); + assert(m.empty()); + assert(m.begin() == m.end()); + assert(m.key_comp() == C(4)); + assert(m.get_allocator() == A{}); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp (revision 304765) @@ -1,77 +1,102 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // multimap(const multimap& m, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef test_allocator A; std::multimap mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(7)); std::multimap m(mo, A(3)); assert(m == mo); assert(m.get_allocator() == A(3)); assert(m.key_comp() == C(5)); assert(mo.get_allocator() == A(7)); assert(mo.key_comp() == C(5)); } #if TEST_STD_VER >= 11 { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef min_allocator A; std::multimap mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); std::multimap m(mo, A()); assert(m == mo); assert(m.get_allocator() == A()); assert(m.key_comp() == C(5)); assert(mo.get_allocator() == A()); assert(mo.key_comp() == C(5)); } + { + typedef std::pair V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + typedef test_compare > C; + typedef explicit_allocator A; + std::multimap mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A{}); + std::multimap m(mo, A{}); + assert(m == mo); + assert(m.get_allocator() == A{}); + assert(m.key_comp() == C(5)); + + assert(mo.get_allocator() == A{}); + assert(mo.key_comp() == C(5)); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/default.pass.cpp (revision 304765) @@ -1,40 +1,54 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // multimap(); #include #include #include "min_allocator.h" int main() { { std::multimap m; assert(m.empty()); assert(m.begin() == m.end()); } #if TEST_STD_VER >= 11 { std::multimap, min_allocator>> m; assert(m.empty()); assert(m.begin() == m.end()); } { + typedef explicit_allocator> A; + { + std::multimap, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::multimap, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + { std::multimap m = {}; assert(m.empty()); assert(m.begin() == m.end()); } #endif } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp (revision 304765) @@ -1,129 +1,163 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // multimap(initializer_list il, const key_compare& comp, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { typedef test_compare > Cmp; typedef test_allocator > A; typedef std::multimap C; typedef C::value_type V; C m( { {1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2} }, Cmp(4), A(5) ); assert(m.size() == 9); assert(distance(m.begin(), m.end()) == 9); C::const_iterator i = m.cbegin(); assert(*i == V(1, 1)); assert(*++i == V(1, 1.5)); assert(*++i == V(1, 2)); assert(*++i == V(2, 1)); assert(*++i == V(2, 1.5)); assert(*++i == V(2, 2)); assert(*++i == V(3, 1)); assert(*++i == V(3, 1.5)); assert(*++i == V(3, 2)); assert(m.key_comp() == Cmp(4)); assert(m.get_allocator() == A(5)); } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #if TEST_STD_VER >= 11 { typedef test_compare > Cmp; typedef min_allocator > A; typedef std::multimap C; typedef C::value_type V; C m( { {1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2} }, Cmp(4), A() ); assert(m.size() == 9); assert(distance(m.begin(), m.end()) == 9); C::const_iterator i = m.cbegin(); assert(*i == V(1, 1)); assert(*++i == V(1, 1.5)); assert(*++i == V(1, 2)); assert(*++i == V(2, 1)); assert(*++i == V(2, 1.5)); assert(*++i == V(2, 2)); assert(*++i == V(3, 1)); assert(*++i == V(3, 1.5)); assert(*++i == V(3, 2)); assert(m.key_comp() == Cmp(4)); assert(m.get_allocator() == A()); } -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef test_compare > C; typedef std::pair V; typedef min_allocator A; typedef std::multimap M; A a; M m ({ {1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2} }, a); assert(m.size() == 9); assert(distance(m.begin(), m.end()) == 9); M::const_iterator i = m.cbegin(); assert(*i == V(1, 1)); assert(*++i == V(1, 1.5)); assert(*++i == V(1, 2)); assert(*++i == V(2, 1)); assert(*++i == V(2, 1.5)); assert(*++i == V(2, 2)); assert(*++i == V(3, 1)); assert(*++i == V(3, 1.5)); assert(*++i == V(3, 2)); assert(m.get_allocator() == a); } #endif + { + typedef test_compare > Cmp; + typedef explicit_allocator > A; + typedef std::multimap C; + typedef C::value_type V; + C m( + { + {1, 1}, + {1, 1.5}, + {1, 2}, + {2, 1}, + {2, 1.5}, + {2, 2}, + {3, 1}, + {3, 1.5}, + {3, 2} + }, + Cmp(4), A{} + ); + assert(m.size() == 9); + assert(distance(m.begin(), m.end()) == 9); + C::const_iterator i = m.cbegin(); + assert(*i == V(1, 1)); + assert(*++i == V(1, 1.5)); + assert(*++i == V(1, 2)); + assert(*++i == V(2, 1)); + assert(*++i == V(2, 1.5)); + assert(*++i == V(2, 2)); + assert(*++i == V(3, 1)); + assert(*++i == V(3, 1.5)); + assert(*++i == V(3, 2)); + assert(m.key_comp() == Cmp(4)); + assert(m.get_allocator() == A{}); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp (revision 304765) @@ -1,91 +1,122 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // template // multimap(InputIterator first, InputIterator last, // const key_compare& comp, const allocator_type& a); #include #include #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef test_allocator A; std::multimap m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(7)); assert(m.get_allocator() == A(7)); assert(m.key_comp() == C(5)); assert(m.size() == 9); assert(distance(m.begin(), m.end()) == 9); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(1, 1.5)); assert(*next(m.begin(), 2) == V(1, 2)); assert(*next(m.begin(), 3) == V(2, 1)); assert(*next(m.begin(), 4) == V(2, 1.5)); assert(*next(m.begin(), 5) == V(2, 2)); assert(*next(m.begin(), 6) == V(3, 1)); assert(*next(m.begin(), 7) == V(3, 1.5)); assert(*next(m.begin(), 8) == V(3, 2)); } #if TEST_STD_VER >= 11 { typedef std::pair V; V ar[] = { V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5), V(3, 2), }; typedef test_compare > C; typedef min_allocator A; std::multimap m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A()); assert(m.get_allocator() == A()); assert(m.key_comp() == C(5)); assert(m.size() == 9); assert(distance(m.begin(), m.end()) == 9); assert(*m.begin() == V(1, 1)); assert(*next(m.begin()) == V(1, 1.5)); assert(*next(m.begin(), 2) == V(1, 2)); assert(*next(m.begin(), 3) == V(2, 1)); assert(*next(m.begin(), 4) == V(2, 1.5)); assert(*next(m.begin(), 5) == V(2, 2)); assert(*next(m.begin(), 6) == V(3, 1)); assert(*next(m.begin(), 7) == V(3, 1.5)); assert(*next(m.begin(), 8) == V(3, 2)); } + { + typedef std::pair V; + V ar[] = + { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + typedef test_compare > C; + typedef explicit_allocator A; + std::multimap m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A{}); + assert(m.get_allocator() == A{}); + assert(m.key_comp() == C(5)); + assert(m.size() == 9); + assert(distance(m.begin(), m.end()) == 9); + assert(*m.begin() == V(1, 1)); + assert(*next(m.begin()) == V(1, 1.5)); + assert(*next(m.begin(), 2) == V(1, 2)); + assert(*next(m.begin(), 3) == V(2, 1)); + assert(*next(m.begin(), 4) == V(2, 1.5)); + assert(*next(m.begin(), 5) == V(2, 2)); + assert(*next(m.begin(), 6) == V(3, 1)); + assert(*next(m.begin(), 7) == V(3, 1.5)); + assert(*next(m.begin(), 8) == V(3, 2)); + } #endif } Index: vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp (revision 304765) @@ -1,234 +1,273 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multimap // multimap(multimap&& m, const allocator_type& a); #include #include #include "MoveOnly.h" #include "../../../test_compare.h" #include "test_allocator.h" #include "min_allocator.h" #include "Counter.h" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef test_allocator A; typedef std::multimap M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A(7)); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A(7)); M m3(std::move(m1), A(7)); assert(m3 == m2); assert(m3.get_allocator() == A(7)); assert(m3.key_comp() == C(5)); assert(m1.empty()); } { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef test_allocator A; typedef std::multimap M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A(7)); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A(7)); M m3(std::move(m1), A(5)); assert(m3 == m2); assert(m3.get_allocator() == A(5)); assert(m3.key_comp() == C(5)); assert(m1.empty()); } { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef other_allocator A; typedef std::multimap M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A(7)); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A(7)); M m3(std::move(m1), A(5)); assert(m3 == m2); assert(m3.get_allocator() == A(5)); assert(m3.key_comp() == C(5)); assert(m1.empty()); } { typedef Counter T; typedef std::pair V; typedef std::pair VC; typedef test_allocator A; typedef std::less C; typedef std::multimap M; typedef V* I; Counter_base::gConstructed = 0; { V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; const size_t num = sizeof(a1)/sizeof(a1[0]); assert(Counter_base::gConstructed == num); M m1(I(a1), I(a1+num), C(), A()); assert(Counter_base::gConstructed == 2*num); M m2(m1); assert(m2 == m1); assert(Counter_base::gConstructed == 3*num); M m3(std::move(m1), A()); assert(m3 == m2); assert(m1.empty()); assert(Counter_base::gConstructed == 3*num); { M m4(std::move(m2), A(5)); assert(Counter_base::gConstructed == 3*num); assert(m4 == m3); assert(m2.empty()); } assert(Counter_base::gConstructed == 2*num); } assert(Counter_base::gConstructed == 0); } #if TEST_STD_VER >= 11 { typedef std::pair V; typedef std::pair VC; typedef test_compare > C; typedef min_allocator A; typedef std::multimap M; typedef std::move_iterator I; V a1[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A()); V a2[] = { V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3) }; M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A()); M m3(std::move(m1), A()); assert(m3 == m2); assert(m3.get_allocator() == A()); assert(m3.key_comp() == C(5)); assert(m1.empty()); } + { + typedef std::pair V; + typedef std::pair VC; + typedef test_compare > C; + typedef explicit_allocator A; + typedef std::multimap M; + typedef std::move_iterator I; + V a1[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A{}); + V a2[] = + { + V(1, 1), + V(1, 2), + V(1, 3), + V(2, 1), + V(2, 2), + V(2, 3), + V(3, 1), + V(3, 2), + V(3, 3) + }; + M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A{}); + M m3(std::move(m1), A{}); + assert(m3 == m2); + assert(m3.get_allocator() == A{}); + assert(m3.key_comp() == C(5)); + assert(m1.empty()); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } Index: vendor/libc++/dist/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/multiset/multiset.cons/default.pass.cpp (revision 304765) @@ -1,40 +1,54 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class multiset // multiset(); #include #include #include "min_allocator.h" int main() { { std::multiset m; assert(m.empty()); assert(m.begin() == m.end()); } #if TEST_STD_VER >= 11 { std::multiset, min_allocator> m; assert(m.empty()); assert(m.begin() == m.end()); } { + typedef explicit_allocator A; + { + std::multiset, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::multiset, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + { std::multiset m = {}; assert(m.empty()); assert(m.begin() == m.end()); } #endif } Index: vendor/libc++/dist/test/std/containers/associative/set/set.cons/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/associative/set/set.cons/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/associative/set/set.cons/default.pass.cpp (revision 304765) @@ -1,40 +1,54 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // class set // set(); #include #include #include "min_allocator.h" int main() { { std::set m; assert(m.empty()); assert(m.begin() == m.end()); } #if TEST_STD_VER >= 11 { std::set, min_allocator> m; assert(m.empty()); assert(m.begin() == m.end()); } { + typedef explicit_allocator A; + { + std::set, A> m; + assert(m.empty()); + assert(m.begin() == m.end()); + } + { + A a; + std::set, A> m(a); + assert(m.empty()); + assert(m.begin() == m.end()); + } + } + { std::set m = {}; assert(m.empty()); assert(m.begin() == m.end()); } #endif } Index: vendor/libc++/dist/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp (revision 304765) @@ -1,38 +1,40 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // explicit deque(const allocator_type& a); #include #include #include "test_allocator.h" #include "../../../NotConstructible.h" #include "min_allocator.h" template void test(const Allocator& a) { std::deque d(a); assert(d.size() == 0); assert(d.get_allocator() == a); } int main() { test(std::allocator()); test(test_allocator(3)); #if TEST_STD_VER >= 11 test(min_allocator()); test(min_allocator{}); + test(explicit_allocator()); + test(explicit_allocator{}); #endif } Index: vendor/libc++/dist/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp (revision 304765) @@ -1,41 +1,49 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // explicit forward_list(const allocator_type& a); #include #include #include "test_allocator.h" #include "../../../NotConstructible.h" #include "min_allocator.h" int main() { { typedef test_allocator A; typedef A::value_type T; typedef std::forward_list C; C c(A(12)); assert(c.get_allocator() == A(12)); assert(c.empty()); } #if TEST_STD_VER >= 11 { typedef min_allocator A; typedef A::value_type T; typedef std::forward_list C; C c(A{}); assert(c.get_allocator() == A()); assert(c.empty()); } + { + typedef explicit_allocator A; + typedef A::value_type T; + typedef std::forward_list C; + C c(A{}); + assert(c.get_allocator() == A()); + assert(c.empty()); + } #endif } Index: vendor/libc++/dist/test/std/containers/sequences/list/list.cons/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/sequences/list/list.cons/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/sequences/list/list.cons/default.pass.cpp (revision 304765) @@ -1,58 +1,68 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // explicit list(const Alloc& = Alloc()); #include #include #include "DefaultOnly.h" #include "min_allocator.h" int main() { { std::list l; assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } { std::list l; assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } { std::list l((std::allocator())); assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } #if TEST_STD_VER >= 11 { std::list> l; assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } { std::list> l; assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } { std::list> l((min_allocator())); assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } { std::list l = {}; assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } + { + std::list> l; + assert(l.size() == 0); + assert(std::distance(l.begin(), l.end()) == 0); + } + { + std::list> l((explicit_allocator())); + assert(l.size() == 0); + assert(std::distance(l.begin(), l.end()) == 0); + } #endif } Index: vendor/libc++/dist/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp (revision 304765) @@ -1,90 +1,102 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // vector(); // vector(const Alloc&); #include #include #include "test_macros.h" #include "test_allocator.h" #include "../../../NotConstructible.h" #include "../../../stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" template void test0() { #if TEST_STD_VER > 14 static_assert((noexcept(C{})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" ); #endif C c; LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == typename C::allocator_type()); LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); #if TEST_STD_VER >= 11 C c1 = {}; LIBCPP_ASSERT(c1.__invariants()); assert(c1.empty()); assert(c1.get_allocator() == typename C::allocator_type()); LIBCPP_ASSERT(is_contiguous_container_asan_correct(c1)); #endif } template void test1(const typename C::allocator_type& a) { #if TEST_STD_VER > 14 static_assert((noexcept(C{typename C::allocator_type{}})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); #endif C c(a); LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == a); LIBCPP_ASSERT(is_contiguous_container_asan_correct(c)); } int main() { { test0 >(); test0 >(); test1 > >(test_allocator(3)); test1 > > (test_allocator(5)); } { std::vector > v; assert(v.empty()); } #if TEST_STD_VER >= 11 { test0> >(); test0> >(); test1 > >(min_allocator{}); test1 > > (min_allocator{}); } { std::vector > v; assert(v.empty()); } + + { + test0> >(); + test0> >(); + test1 > >(explicit_allocator{}); + test1 > > + (explicit_allocator{}); + } + { + std::vector > v; + assert(v.empty()); + } #endif } Index: vendor/libc++/dist/test/std/containers/sequences/vector.bool/construct_default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/sequences/vector.bool/construct_default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/sequences/vector.bool/construct_default.pass.cpp (revision 304765) @@ -1,70 +1,74 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // vector // vector(const Alloc& = Alloc()); #include #include #include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" template void test0() { #if TEST_STD_VER > 14 static_assert((noexcept(C{})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" ); #endif C c; LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == typename C::allocator_type()); #if TEST_STD_VER >= 11 C c1 = {}; LIBCPP_ASSERT(c1.__invariants()); assert(c1.empty()); assert(c1.get_allocator() == typename C::allocator_type()); #endif } template void test1(const typename C::allocator_type& a) { #if TEST_STD_VER > 14 static_assert((noexcept(C{typename C::allocator_type{}})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); #endif C c(a); LIBCPP_ASSERT(c.__invariants()); assert(c.empty()); assert(c.get_allocator() == a); } int main() { { test0 >(); test1 > >(test_allocator(3)); } #if TEST_STD_VER >= 11 { test0> >(); test1 > >(min_allocator()); } + { + test0> >(); + test1 > >(explicit_allocator()); + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp (revision 304765) @@ -1,111 +1,129 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // explicit unordered_map(const allocator_type& __a); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_map >, test_compare >, test_allocator > > C; C c(test_allocator >(10)); assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (test_allocator >(10))); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_map >, test_compare >, min_allocator > > C; C c(min_allocator >{}); assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (min_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } -#if _LIBCPP_STD_VER > 11 + { + typedef explicit_allocator> A; + typedef std::unordered_map >, + test_compare >, + A + > C; + C c(A{}); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } +#if TEST_STD_VER > 11 { typedef NotConstructible T; typedef test_allocator> A; typedef test_hash> HF; typedef test_compare> Comp; typedef std::unordered_map C; A a(10); C c(2, a); assert(c.bucket_count() == 2); assert(c.hash_function() == HF()); assert(c.key_eq() == Comp()); assert(c.get_allocator() == a); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } { typedef NotConstructible T; typedef test_allocator> A; typedef test_hash> HF; typedef test_compare> Comp; typedef std::unordered_map C; A a(10); HF hf(12); C c(2, hf, a); assert(c.bucket_count() == 2); assert(c.hash_function() == hf); assert(!(c.hash_function() == HF())); assert(c.key_eq() == Comp()); assert(c.get_allocator() == a); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #endif #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp (revision 304765) @@ -1,111 +1,150 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // unordered_map(const unordered_map& u, const allocator_type& a); #include #include #include #include #include #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_map >, test_compare >, test_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), test_allocator >(10) ); C c(c0, test_allocator >(5)); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (test_allocator >(5))); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_map >, test_compare >, min_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), min_allocator >() ); C c(c0, min_allocator >()); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (min_allocator >())); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator> A; + typedef std::unordered_map >, + test_compare >, + A + > C; + typedef std::pair P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + C c(c0, A{}); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp (revision 304765) @@ -1,78 +1,111 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // unordered_map(); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_map >, test_compare >, test_allocator > > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (test_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_map >, test_compare >, min_allocator > > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (min_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } { + typedef explicit_allocator> A; + typedef std::unordered_map >, + test_compare >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + { std::unordered_map c = {}; assert(c.bucket_count() == 0); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp (revision 304765) @@ -1,108 +1,144 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // unordered_map(initializer_list il, size_type n, // const hasher& hf, const key_equal& eql, const allocator_type& a); #include #include #include #include #include #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { typedef std::unordered_map >, test_compare >, test_allocator > > C; typedef std::pair P; C c({ P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }, 7, test_hash >(8), test_compare >(9), test_allocator >(10) ); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (test_allocator >(10))); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_map >, test_compare >, min_allocator > > C; typedef std::pair P; C c({ P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }, 7, test_hash >(8), test_compare >(9), min_allocator >() ); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (min_allocator >())); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator> A; + typedef std::unordered_map >, + test_compare >, + A + > C; + typedef std::pair P; + C c({ + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }, + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + } #endif #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp (revision 304765) @@ -1,158 +1,199 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // unordered_map(unordered_map&& u, const allocator_type& a); #include #include #include #include #include #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::pair P; typedef test_allocator> A; typedef std::unordered_map >, test_compare >, A > C; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), A(10) ); C c(std::move(c0), A(12)); assert(c.bucket_count() >= 5); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == A(12)); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c0.empty()); } { typedef std::pair P; typedef test_allocator> A; typedef std::unordered_map >, test_compare >, A > C; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), A(10) ); C c(std::move(c0), A(10)); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == A(10)); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c0.empty()); } #if TEST_STD_VER >= 11 { typedef std::pair P; typedef min_allocator> A; typedef std::unordered_map >, test_compare >, A > C; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), A() ); C c(std::move(c0), A()); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == A()); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c0.empty()); } + { + typedef std::pair P; + typedef explicit_allocator> A; + typedef std::unordered_map >, + test_compare >, + A + > C; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + C c(std::move(c0), A{}); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + + assert(c0.empty()); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp (revision 304765) @@ -1,114 +1,152 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // template // unordered_map(InputIterator first, InputIterator last, size_type n, // const hasher& hf, const key_equal& eql, // const allocator_type& a); #include #include #include #include #include #include "test_iterators.h" #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_map >, test_compare >, test_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0])), 7, test_hash >(8), test_compare >(9), test_allocator >(10) ); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (test_allocator >(10))); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_map >, test_compare >, min_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0])), 7, test_hash >(8), test_compare >(9), min_allocator >() ); assert(c.bucket_count() == 7); assert(c.size() == 4); assert(c.at(1) == "one"); assert(c.at(2) == "two"); assert(c.at(3) == "three"); assert(c.at(4) == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (min_allocator >())); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator> A; + typedef std::unordered_map >, + test_compare >, + A + > C; + typedef std::pair P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0])), + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 4); + assert(c.at(1) == "one"); + assert(c.at(2) == "two"); + assert(c.at(3) == "three"); + assert(c.at(4) == "four"); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp (revision 304765) @@ -1,77 +1,99 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_map // unordered_map(size_type n, const hasher& hf, const key_equal& eql, const allocator_type& a); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_map >, test_compare >, test_allocator > > C; C c(7, test_hash >(8), test_compare >(9), test_allocator >(10) ); assert(c.bucket_count() == 7); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (test_allocator >(10))); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_map >, test_compare >, min_allocator > > C; C c(7, test_hash >(8), test_compare >(9), min_allocator >() ); assert(c.bucket_count() == 7); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (min_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator > A; + typedef std::unordered_map >, + test_compare >, + A + > C; + C c(7, + test_hash >(8), + test_compare >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp (revision 304765) @@ -1,111 +1,129 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // explicit unordered_multimap(const allocator_type& __a); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_multimap >, test_compare >, test_allocator > > C; C c(test_allocator >(10)); assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (test_allocator >(10))); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap >, test_compare >, min_allocator > > C; C c(min_allocator >{}); assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (min_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator> A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + C c(A{}); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } #if _LIBCPP_STD_VER > 11 { typedef NotConstructible T; typedef test_allocator> A; typedef test_hash> HF; typedef test_compare> Comp; typedef std::unordered_multimap C; A a(10); C c(2, a); assert(c.bucket_count() == 2); assert(c.hash_function() == HF()); assert(c.key_eq() == Comp()); assert(c.get_allocator() == a); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } { typedef NotConstructible T; typedef test_allocator> A; typedef test_hash> HF; typedef test_compare> Comp; typedef std::unordered_multimap C; A a(10); HF hf(12); C c(2, hf, a); assert(c.bucket_count() == 2); assert(c.hash_function() == hf); assert(!(c.hash_function() == HF())); assert(c.key_eq() == Comp()); assert(c.get_allocator() == a); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #endif #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp (revision 304765) @@ -1,139 +1,192 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // unordered_multimap(const unordered_multimap& u, const allocator_type& a); #include #include #include #include #include #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_multimap >, test_compare >, test_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), test_allocator >(10) ); C c(c0, test_allocator >(5)); assert(c.bucket_count() == 7); assert(c.size() == 6); C::const_iterator i = c.cbegin(); assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); ++i; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); ++i; assert(i->first == 3); assert(i->second == "three"); ++i; assert(i->first == 4); assert(i->second == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (test_allocator >(5))); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap >, test_compare >, min_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), min_allocator >() ); C c(c0, min_allocator >()); assert(c.bucket_count() == 7); assert(c.size() == 6); C::const_iterator i = c.cbegin(); assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); ++i; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); ++i; assert(i->first == 3); assert(i->second == "three"); ++i; assert(i->first == 4); assert(i->second == "four"); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (min_allocator >())); assert(!c.empty()); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator> A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + typedef std::pair P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + C c(c0, A{}); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + C::const_iterator i = c.cbegin(); + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + ++i; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + ++i; + assert(i->first == 3); + assert(i->second == "three"); + ++i; + assert(i->first == 4); + assert(i->second == "four"); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(!c.empty()); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp (revision 304765) @@ -1,78 +1,111 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // unordered_multimap(); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_multimap >, test_compare >, test_allocator > > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (test_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap >, test_compare >, min_allocator > > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (min_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } { + typedef explicit_allocator> A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + { std::unordered_multimap c = {}; assert(c.bucket_count() == 0); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp (revision 304765) @@ -1,152 +1,211 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // unordered_multimap(initializer_list il, size_type n, // const hasher& hf, const key_equal& eql, const allocator_type& a); #include #include #include #include #include #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS { typedef std::unordered_multimap >, test_compare >, test_allocator > > C; typedef std::pair P; C c({ P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }, 7, test_hash >(8), test_compare >(9), test_allocator >(10) ); assert(c.bucket_count() == 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == test_allocator >(10))); } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap >, test_compare >, min_allocator > > C; typedef std::pair P; C c({ P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }, 7, test_hash >(8), test_compare >(9), min_allocator >() ); assert(c.bucket_count() == 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == min_allocator >())); } + { + typedef explicit_allocator> A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + typedef std::pair P; + C c({ + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }, + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + typedef std::pair Eq; + Eq eq = c.equal_range(1); + assert(std::distance(eq.first, eq.second) == 2); + C::const_iterator i = eq.first; + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + eq = c.equal_range(2); + assert(std::distance(eq.first, eq.second) == 2); + i = eq.first; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + + eq = c.equal_range(3); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 3); + assert(i->second == "three"); + eq = c.equal_range(4); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 4); + assert(i->second == "four"); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + } #endif #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp (revision 304765) @@ -1,229 +1,293 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // unordered_multimap(unordered_multimap&& u, const allocator_type& a); #include #include #include #include #include #include #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::pair P; typedef test_allocator> A; typedef std::unordered_multimap >, test_compare >, A > C; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), A(10) ); C c(std::move(c0), A(12)); assert(c.bucket_count() >= 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == test_allocator >(12))); assert(c0.empty()); } { typedef std::pair P; typedef test_allocator> A; typedef std::unordered_multimap >, test_compare >, A > C; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), A(10) ); C c(std::move(c0), A(10)); assert(c.bucket_count() == 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == test_allocator >(10))); assert(c0.empty()); } #if TEST_STD_VER >= 11 { typedef std::pair P; typedef min_allocator> A; typedef std::unordered_multimap >, test_compare >, A > C; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c0(a, a + sizeof(a)/sizeof(a[0]), 7, test_hash >(8), test_compare >(9), A() ); C c(std::move(c0), A()); assert(c.bucket_count() == 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == min_allocator >())); assert(c0.empty()); } + { + typedef std::pair P; + typedef explicit_allocator> A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c0(a, a + sizeof(a)/sizeof(a[0]), + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + C c(std::move(c0), A()); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + typedef std::pair Eq; + Eq eq = c.equal_range(1); + assert(std::distance(eq.first, eq.second) == 2); + C::const_iterator i = eq.first; + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + eq = c.equal_range(2); + assert(std::distance(eq.first, eq.second) == 2); + i = eq.first; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + + eq = c.equal_range(3); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 3); + assert(i->second == "three"); + eq = c.equal_range(4); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 4); + assert(i->second == "four"); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + + assert(c0.empty()); + } #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp (revision 304765) @@ -1,158 +1,219 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // template // unordered_multimap(InputIterator first, InputIterator last, size_type n, // const hasher& hf, const key_equal& eql, // const allocator_type& a); #include #include #include #include #include #include "test_iterators.h" #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_multimap >, test_compare >, test_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0])), 7, test_hash >(8), test_compare >(9), test_allocator >(10) ); assert(c.bucket_count() == 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == test_allocator >(10))); } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap >, test_compare >, min_allocator > > C; typedef std::pair P; P a[] = { P(1, "one"), P(2, "two"), P(3, "three"), P(4, "four"), P(1, "four"), P(2, "four"), }; C c(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0])), 7, test_hash >(8), test_compare >(9), min_allocator >() ); assert(c.bucket_count() == 7); assert(c.size() == 6); typedef std::pair Eq; Eq eq = c.equal_range(1); assert(std::distance(eq.first, eq.second) == 2); C::const_iterator i = eq.first; assert(i->first == 1); assert(i->second == "one"); ++i; assert(i->first == 1); assert(i->second == "four"); eq = c.equal_range(2); assert(std::distance(eq.first, eq.second) == 2); i = eq.first; assert(i->first == 2); assert(i->second == "two"); ++i; assert(i->first == 2); assert(i->second == "four"); eq = c.equal_range(3); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 3); assert(i->second == "three"); eq = c.equal_range(4); assert(std::distance(eq.first, eq.second) == 1); i = eq.first; assert(i->first == 4); assert(i->second == "four"); assert(std::distance(c.begin(), c.end()) == c.size()); assert(std::distance(c.cbegin(), c.cend()) == c.size()); assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); assert(c.max_load_factor() == 1); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert((c.get_allocator() == min_allocator >())); } + { + typedef explicit_allocator> A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + typedef std::pair P; + P a[] = + { + P(1, "one"), + P(2, "two"), + P(3, "three"), + P(4, "four"), + P(1, "four"), + P(2, "four"), + }; + C c(input_iterator(a), input_iterator(a + sizeof(a)/sizeof(a[0])), + 7, + test_hash >(8), + test_compare >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.size() == 6); + typedef std::pair Eq; + Eq eq = c.equal_range(1); + assert(std::distance(eq.first, eq.second) == 2); + C::const_iterator i = eq.first; + assert(i->first == 1); + assert(i->second == "one"); + ++i; + assert(i->first == 1); + assert(i->second == "four"); + eq = c.equal_range(2); + assert(std::distance(eq.first, eq.second) == 2); + i = eq.first; + assert(i->first == 2); + assert(i->second == "two"); + ++i; + assert(i->first == 2); + assert(i->second == "four"); + + eq = c.equal_range(3); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 3); + assert(i->second == "three"); + eq = c.equal_range(4); + assert(std::distance(eq.first, eq.second) == 1); + i = eq.first; + assert(i->first == 4); + assert(i->second == "four"); + assert(std::distance(c.begin(), c.end()) == c.size()); + assert(std::distance(c.cbegin(), c.cend()) == c.size()); + assert(std::fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON); + assert(c.max_load_factor() == 1); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{});; + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp (revision 304765) @@ -1,77 +1,99 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator>> // class unordered_multimap // unordered_multimap(size_type n, const hasher& hf, const key_equal& eql, const allocator_type& a); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_multimap >, test_compare >, test_allocator > > C; C c(7, test_hash >(8), test_compare >(9), test_allocator >(10) ); assert(c.bucket_count() == 7); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (test_allocator >(10))); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_multimap >, test_compare >, min_allocator > > C; C c(7, test_hash >(8), test_compare >(9), min_allocator >() ); assert(c.bucket_count() == 7); assert(c.hash_function() == test_hash >(8)); assert(c.key_eq() == test_compare >(9)); assert(c.get_allocator() == (min_allocator >())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } + { + typedef explicit_allocator > A; + typedef std::unordered_multimap >, + test_compare >, + A + > C; + C c(7, + test_hash >(8), + test_compare >(9), + A{} + ); + LIBCPP_ASSERT(c.bucket_count() == 7); + assert(c.hash_function() == test_hash >(8)); + assert(c.key_eq() == test_compare >(9)); + assert(c.get_allocator() == A{}); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp (revision 304765) @@ -1,74 +1,107 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator> // class unordered_multiset // unordered_multiset(); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_multiset >, test_compare >, test_allocator > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (test_allocator())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_multiset >, test_compare >, min_allocator > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (min_allocator())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } { + typedef explicit_allocator A; + typedef std::unordered_multiset >, + test_compare >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + { std::unordered_multiset c = {}; assert(c.bucket_count() == 0); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #endif } Index: vendor/libc++/dist/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/containers/unord/unord.set/unord.set.cnstr/default.pass.cpp (revision 304765) @@ -1,74 +1,107 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // template , class Pred = equal_to, // class Alloc = allocator> // class unordered_set // unordered_set(); #include #include #include "../../../NotConstructible.h" #include "../../../test_compare.h" #include "../../../test_hash.h" #include "test_allocator.h" #include "min_allocator.h" int main() { { typedef std::unordered_set >, test_compare >, test_allocator > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (test_allocator())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #if TEST_STD_VER >= 11 { typedef std::unordered_set >, test_compare >, min_allocator > C; C c; assert(c.bucket_count() == 0); assert(c.hash_function() == test_hash >()); assert(c.key_eq() == test_compare >()); assert(c.get_allocator() == (min_allocator())); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } { + typedef explicit_allocator A; + typedef std::unordered_set >, + test_compare >, + A + > C; + { + C c; + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == A()); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + { + A a; + C c(a); + LIBCPP_ASSERT(c.bucket_count() == 0); + assert(c.hash_function() == test_hash >()); + assert(c.key_eq() == test_compare >()); + assert(c.get_allocator() == a); + assert(c.size() == 0); + assert(c.empty()); + assert(std::distance(c.begin(), c.end()) == 0); + assert(c.load_factor() == 0); + assert(c.max_load_factor() == 1); + } + } + { std::unordered_set c = {}; assert(c.bucket_count() == 0); assert(c.size() == 0); assert(c.empty()); assert(std::distance(c.begin(), c.end()) == 0); assert(c.load_factor() == 0); assert(c.max_load_factor() == 1); } #endif } Index: vendor/libc++/dist/test/std/strings/basic.string/string.cons/alloc.pass.cpp =================================================================== --- vendor/libc++/dist/test/std/strings/basic.string/string.cons/alloc.pass.cpp (revision 304764) +++ vendor/libc++/dist/test/std/strings/basic.string/string.cons/alloc.pass.cpp (revision 304765) @@ -1,95 +1,96 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // explicit basic_string(const Allocator& a = Allocator()); #include #include #include "test_macros.h" #include "test_allocator.h" #include "min_allocator.h" template void test() { { #if TEST_STD_VER > 14 static_assert((noexcept(S{})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" ); #endif S s; LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); assert(s.get_allocator() == typename S::allocator_type()); } { #if TEST_STD_VER > 14 static_assert((noexcept(S{typename S::allocator_type{}})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(S(typename S::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); #endif S s(typename S::allocator_type(5)); LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); assert(s.get_allocator() == typename S::allocator_type(5)); } } #if TEST_STD_VER >= 11 template void test2() { { #if TEST_STD_VER > 14 static_assert((noexcept(S{})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" ); #endif S s; LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); assert(s.get_allocator() == typename S::allocator_type()); } { #if TEST_STD_VER > 14 static_assert((noexcept(S{typename S::allocator_type{}})), "" ); #elif TEST_STD_VER >= 11 static_assert((noexcept(S(typename S::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); #endif S s(typename S::allocator_type{}); LIBCPP_ASSERT(s.__invariants()); assert(s.data()); assert(s.size() == 0); assert(s.capacity() >= s.size()); assert(s.get_allocator() == typename S::allocator_type()); } } #endif int main() { test, test_allocator > >(); #if TEST_STD_VER >= 11 test2, min_allocator > >(); + test2, explicit_allocator > >(); #endif } Index: vendor/libc++/dist/test/support/min_allocator.h =================================================================== --- vendor/libc++/dist/test/support/min_allocator.h (revision 304764) +++ vendor/libc++/dist/test/support/min_allocator.h (revision 304765) @@ -1,345 +1,370 @@ //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MIN_ALLOCATOR_H #define MIN_ALLOCATOR_H #include #include #include #include #include "test_macros.h" template class bare_allocator { public: typedef T value_type; bare_allocator() TEST_NOEXCEPT {} template bare_allocator(bare_allocator) TEST_NOEXCEPT {} T* allocate(std::size_t n) { return static_cast(::operator new(n*sizeof(T))); } void deallocate(T* p, std::size_t) { return ::operator delete(static_cast(p)); } friend bool operator==(bare_allocator, bare_allocator) {return true;} friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);} }; struct malloc_allocator_base { static size_t alloc_count; static size_t dealloc_count; static bool disable_default_constructor; static size_t outstanding_alloc() { assert(alloc_count >= dealloc_count); return (alloc_count - dealloc_count); } static void reset() { assert(outstanding_alloc() == 0); disable_default_constructor = false; alloc_count = 0; dealloc_count = 0; } }; size_t malloc_allocator_base::alloc_count = 0; size_t malloc_allocator_base::dealloc_count = 0; bool malloc_allocator_base::disable_default_constructor = false; template class malloc_allocator : public malloc_allocator_base { public: typedef T value_type; malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); } template malloc_allocator(malloc_allocator) TEST_NOEXCEPT {} T* allocate(std::size_t n) { ++alloc_count; return static_cast(std::malloc(n*sizeof(T))); } void deallocate(T* p, std::size_t) { ++dealloc_count; std::free(static_cast(p)); } friend bool operator==(malloc_allocator, malloc_allocator) {return true;} friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);} }; #if TEST_STD_VER >= 11 #include template class min_pointer; template class min_pointer; template <> class min_pointer; template <> class min_pointer; template class min_allocator; template <> class min_pointer { const void* ptr_; public: min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} template min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(p.ptr_) {} explicit operator bool() const {return ptr_ != nullptr;} friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} template friend class min_pointer; }; template <> class min_pointer { void* ptr_; public: min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} template ::value >::type > min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(p.ptr_) {} explicit operator bool() const {return ptr_ != nullptr;} friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} template friend class min_pointer; }; template class min_pointer { T* ptr_; explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {} public: min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} explicit min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(static_cast(p.ptr_)) {} explicit operator bool() const {return ptr_ != nullptr;} typedef std::ptrdiff_t difference_type; typedef T& reference; typedef T* pointer; typedef T value_type; typedef std::random_access_iterator_tag iterator_category; reference operator*() const {return *ptr_;} pointer operator->() const {return ptr_;} min_pointer& operator++() {++ptr_; return *this;} min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} min_pointer& operator--() {--ptr_; return *this;} min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} min_pointer operator+(difference_type n) const { min_pointer tmp(*this); tmp += n; return tmp; } friend min_pointer operator+(difference_type n, min_pointer x) { return x + n; } min_pointer operator-(difference_type n) const { min_pointer tmp(*this); tmp -= n; return tmp; } friend difference_type operator-(min_pointer x, min_pointer y) { return x.ptr_ - y.ptr_; } reference operator[](difference_type n) const {return ptr_[n];} friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} friend bool operator> (min_pointer x, min_pointer y) {return y < x;} friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));} friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} template friend class min_pointer; template friend class min_allocator; }; template class min_pointer { const T* ptr_; explicit min_pointer(const T* p) : ptr_(p) {} public: min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t) : ptr_(nullptr) {} min_pointer(min_pointer p) : ptr_(p.ptr_) {} explicit min_pointer(min_pointer p) : ptr_(static_cast(p.ptr_)) {} explicit operator bool() const {return ptr_ != nullptr;} typedef std::ptrdiff_t difference_type; typedef const T& reference; typedef const T* pointer; typedef const T value_type; typedef std::random_access_iterator_tag iterator_category; reference operator*() const {return *ptr_;} pointer operator->() const {return ptr_;} min_pointer& operator++() {++ptr_; return *this;} min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} min_pointer& operator--() {--ptr_; return *this;} min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} min_pointer operator+(difference_type n) const { min_pointer tmp(*this); tmp += n; return tmp; } friend min_pointer operator+(difference_type n, min_pointer x) { return x + n; } min_pointer operator-(difference_type n) const { min_pointer tmp(*this); tmp -= n; return tmp; } friend difference_type operator-(min_pointer x, min_pointer y) { return x.ptr_ - y.ptr_; } reference operator[](difference_type n) const {return ptr_[n];} friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} friend bool operator> (min_pointer x, min_pointer y) {return y < x;} friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));} friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} template friend class min_pointer; }; template inline bool operator==(min_pointer x, std::nullptr_t) { return !static_cast(x); } template inline bool operator==(std::nullptr_t, min_pointer x) { return !static_cast(x); } template inline bool operator!=(min_pointer x, std::nullptr_t) { return static_cast(x); } template inline bool operator!=(std::nullptr_t, min_pointer x) { return static_cast(x); } template class min_allocator { public: typedef T value_type; typedef min_pointer pointer; min_allocator() = default; template min_allocator(min_allocator) {} pointer allocate(std::ptrdiff_t n) { return pointer(static_cast(::operator new(n*sizeof(T)))); } void deallocate(pointer p, std::ptrdiff_t) { return ::operator delete(p.ptr_); } friend bool operator==(min_allocator, min_allocator) {return true;} friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);} }; +template +class explicit_allocator +{ +public: + typedef T value_type; + + explicit_allocator() TEST_NOEXCEPT {} + + template + explicit explicit_allocator(explicit_allocator) TEST_NOEXCEPT {} + + T* allocate(std::size_t n) + { + return static_cast(::operator new(n*sizeof(T))); + } + + void deallocate(T* p, std::size_t) + { + return ::operator delete(static_cast(p)); + } + + friend bool operator==(explicit_allocator, explicit_allocator) {return true;} + friend bool operator!=(explicit_allocator x, explicit_allocator y) {return !(x == y);} +}; + #endif // TEST_STD_VER >= 11 #endif // MIN_ALLOCATOR_H