diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2010-10-28 16:01:05 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2010-10-28 16:01:05 +0000 |
commit | fb7342fd6f834c6786278eeb9d99d704c2f6a0a1 (patch) | |
tree | 8c058c4b504e6a5cbf998753e6c41978cf0ba81f /libstdc++-v3 | |
parent | d724c8f0a9ea6bbb8bfd10fc00754902093e40ce (diff) | |
download | gcc-fb7342fd6f834c6786278eeb9d99d704c2f6a0a1.zip gcc-fb7342fd6f834c6786278eeb9d99d704c2f6a0a1.tar.gz gcc-fb7342fd6f834c6786278eeb9d99d704c2f6a0a1.tar.bz2 |
PR libstdc++/44436 (partial)
2010-10-28 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/44436 (partial)
* include/bits/hashtable.h (_Hashtable<>::insert(value_type&&),
insert(_Pair&&), insert(const_iterator, value_type&&),
insert(const_iterator, _Pair&&)): Add.
(_M_allocate_node, _M_insert, _M_insert_bucket): Templatize.
* include/bits/hashtable_policy.h (__detail::_Select1st): Add; use
it throughout.
(_Map_base<>::operator[](_Key&&)): Add.
* include/bits/unordered_map.h: Use __detail::_Select1st throughout.
* include/debug/unordered_map: Update.
* include/debug/unordered_set: Likewise.
* include/profile/unordered_map: Likewise.
* include/profile/unordered_set: Likewise.
* testsuite/util/testsuite_rvalref.h (struct hash<rvalstruct>): Add;
minor tweaks throughout, use deleted special members.
* testsuite/23_containers/unordered_map/insert/map_single_move-1.cc:
New.
* testsuite/23_containers/unordered_map/insert/map_single_move-2.cc:
Likewise.
* testsuite/23_containers/unordered_map/insert/array_syntax_move.cc:
Likewise.
* testsuite/23_containers/unordered_multimap/insert/
multimap_single_move-1.cc: Likewise.
* testsuite/23_containers/unordered_multimap/insert/
multimap_single_move-2.cc: Likewise.
* testsuite/23_containers/unordered_set/insert/set_single_move.cc:
Likewise.
* testsuite/23_containers/unordered_multiset/insert/
multiset_single_move.cc: Likewise.
* testsuite/23_containers/unordered_map/insert/array_syntax.cc:
Minor cosmetic changes.
From-SVN: r166030
Diffstat (limited to 'libstdc++-v3')
17 files changed, 959 insertions, 186 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 05bfcbd..8b5b94a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,38 @@ +2010-10-28 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/44436 (partial) + * include/bits/hashtable.h (_Hashtable<>::insert(value_type&&), + insert(_Pair&&), insert(const_iterator, value_type&&), + insert(const_iterator, _Pair&&)): Add. + (_M_allocate_node, _M_insert, _M_insert_bucket): Templatize. + * include/bits/hashtable_policy.h (__detail::_Select1st): Add; use + it throughout. + (_Map_base<>::operator[](_Key&&)): Add. + * include/bits/unordered_map.h: Use __detail::_Select1st throughout. + * include/debug/unordered_map: Update. + * include/debug/unordered_set: Likewise. + * include/profile/unordered_map: Likewise. + * include/profile/unordered_set: Likewise. + * testsuite/util/testsuite_rvalref.h (struct hash<rvalstruct>): Add; + minor tweaks throughout, use deleted special members. + * testsuite/23_containers/unordered_map/insert/map_single_move-1.cc: + New. + * testsuite/23_containers/unordered_map/insert/map_single_move-2.cc: + Likewise. + * testsuite/23_containers/unordered_map/insert/array_syntax_move.cc: + Likewise. + * testsuite/23_containers/unordered_multimap/insert/ + multimap_single_move-1.cc: Likewise. + * testsuite/23_containers/unordered_multimap/insert/ + multimap_single_move-2.cc: Likewise. + * testsuite/23_containers/unordered_set/insert/set_single_move.cc: + Likewise. + * testsuite/23_containers/unordered_multiset/insert/ + multiset_single_move.cc: Likewise. + + * testsuite/23_containers/unordered_map/insert/array_syntax.cc: + Minor cosmetic changes. + 2010-10-27 Jason Merrill <jason@redhat.com> * include/std/type_traits (is_literal_type): New. diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index dd8c1c2..343a122 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -178,9 +178,10 @@ namespace std size_type _M_begin_bucket_index; // First non-empty bucket. size_type _M_element_count; _RehashPolicy _M_rehash_policy; - - _Node* - _M_allocate_node(const value_type& __v); + + template<typename... _Args> + _Node* + _M_allocate_node(_Args&&... __args); void _M_deallocate_node(_Node* __n); @@ -360,11 +361,27 @@ namespace std std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const; - private: // Find, insert and erase helper functions - // ??? This dispatching is a workaround for the fact that we don't - // have partial specialization of member templates; it would be - // better to just specialize insert on __unique_keys. There may be a - // cleaner workaround. + private: + // Find, insert and erase helper functions + _Node* + _M_find_node(_Node*, const key_type&, + typename _Hashtable::_Hash_code_type) const; + + template<typename _Pair> + iterator + _M_insert_bucket(_Pair&&, size_type, + typename _Hashtable::_Hash_code_type); + + template<typename _Pair> + std::pair<iterator, bool> + _M_insert(_Pair&&, std::true_type); + + template<typename _Pair> + iterator + _M_insert(_Pair&&, std::false_type); + + public: + // Insert and erase typedef typename std::conditional<__unique_keys, std::pair<iterator, bool>, iterator>::type @@ -376,30 +393,39 @@ namespace std >::type _Insert_Conv_Type; - _Node* - _M_find_node(_Node*, const key_type&, - typename _Hashtable::_Hash_code_type) const; - - iterator - _M_insert_bucket(const value_type&, size_type, - typename _Hashtable::_Hash_code_type); - - std::pair<iterator, bool> - _M_insert(const value_type&, std::true_type); + _Insert_Return_Type + insert(const value_type& __v) + { return _M_insert(__v, std::integral_constant<bool, __unique_keys>()); } iterator - _M_insert(const value_type&, std::false_type); + insert(const_iterator, const value_type& __v) + { return _Insert_Conv_Type()(insert(__v)); } - public: - // Insert and erase _Insert_Return_Type - insert(const value_type& __v) - { return _M_insert(__v, std::integral_constant<bool, - __unique_keys>()); } + insert(value_type&& __v) + { return _M_insert(std::move(__v), + std::integral_constant<bool, __unique_keys>()); } iterator - insert(const_iterator, const value_type& __v) - { return iterator(_Insert_Conv_Type()(this->insert(__v))); } + insert(const_iterator, value_type&& __v) + { return _Insert_Conv_Type()(insert(std::move(__v))); } + + template<typename _Pair, typename = typename + std::enable_if<!__constant_iterators + && std::is_convertible<_Pair, + value_type>::value>::type> + _Insert_Return_Type + insert(_Pair&& __v) + { return _M_insert(std::forward<_Pair>(__v), + std::integral_constant<bool, __unique_keys>()); } + + template<typename _Pair, typename = typename + std::enable_if<!__constant_iterators + && std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(const_iterator, _Pair&& __v) + { return _Insert_Conv_Type()(insert(std::forward<_Pair>(__v))); } template<typename _InputIterator> void @@ -438,26 +464,27 @@ namespace std typename _Allocator, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, bool __chc, bool __cit, bool __uk> - typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, - __chc, __cit, __uk>::_Node* - _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: - _M_allocate_node(const value_type& __v) - { - _Node* __n = _M_node_allocator.allocate(1); - __try - { - _M_node_allocator.construct(__n, __v); - __n->_M_next = 0; - return __n; - } - __catch(...) - { - _M_node_allocator.deallocate(__n, 1); - __throw_exception_again; - } - } + template<typename... _Args> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::_Node* + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_allocate_node(_Args&&... __args) + { + _Node* __n = _M_node_allocator.allocate(1); + __try + { + _M_node_allocator.construct(__n, std::forward<_Args>(__args)...); + __n->_M_next = 0; + return __n; + } + __catch(...) + { + _M_node_allocator.deallocate(__n, 1); + __throw_exception_again; + } + } template<typename _Key, typename _Value, typename _Allocator, typename _ExtractKey, typename _Equal, @@ -871,111 +898,117 @@ namespace std typename _Allocator, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, bool __chc, bool __cit, bool __uk> - typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, - __chc, __cit, __uk>::iterator - _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: - _M_insert_bucket(const value_type& __v, size_type __n, - typename _Hashtable::_Hash_code_type __code) - { - std::pair<bool, std::size_t> __do_rehash - = _M_rehash_policy._M_need_rehash(_M_bucket_count, - _M_element_count, 1); + template<typename _Pair> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert_bucket(_Pair&& __v, size_type __n, + typename _Hashtable::_Hash_code_type __code) + { + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, 1); - // Allocate the new node before doing the rehash so that we don't - // do a rehash if the allocation throws. - _Node* __new_node = _M_allocate_node(__v); + if (__do_rehash.first) + { + const key_type& __k = this->_M_extract(__v); + __n = this->_M_bucket_index(__k, __code, __do_rehash.second); + } - __try - { - if (__do_rehash.first) - { - const key_type& __k = this->_M_extract(__v); - __n = this->_M_bucket_index(__k, __code, __do_rehash.second); + // Allocate the new node before doing the rehash so that we don't + // do a rehash if the allocation throws. + _Node* __new_node = _M_allocate_node(std::forward<_Pair>(__v)); + + __try + { + if (__do_rehash.first) _M_rehash(__do_rehash.second); - } - __new_node->_M_next = _M_buckets[__n]; - this->_M_store_code(__new_node, __code); - _M_buckets[__n] = __new_node; - ++_M_element_count; - if (__n < _M_begin_bucket_index) - _M_begin_bucket_index = __n; - return iterator(__new_node, _M_buckets + __n); - } - __catch(...) - { - _M_deallocate_node(__new_node); - __throw_exception_again; - } - } + __new_node->_M_next = _M_buckets[__n]; + this->_M_store_code(__new_node, __code); + _M_buckets[__n] = __new_node; + ++_M_element_count; + if (__n < _M_begin_bucket_index) + _M_begin_bucket_index = __n; + return iterator(__new_node, _M_buckets + __n); + } + __catch(...) + { + _M_deallocate_node(__new_node); + __throw_exception_again; + } + } // Insert v if no element with its key is already present. template<typename _Key, typename _Value, typename _Allocator, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, bool __chc, bool __cit, bool __uk> - std::pair<typename _Hashtable<_Key, _Value, _Allocator, - _ExtractKey, _Equal, _H1, - _H2, _Hash, _RehashPolicy, - __chc, __cit, __uk>::iterator, bool> - _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: - _M_insert(const value_type& __v, std::true_type) - { - const key_type& __k = this->_M_extract(__v); - typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); - size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); - - if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code)) - return std::make_pair(iterator(__p, _M_buckets + __n), false); - return std::make_pair(_M_insert_bucket(__v, __n, __code), true); - } + template<typename _Pair> + std::pair<typename _Hashtable<_Key, _Value, _Allocator, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator, bool> + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert(_Pair&& __v, std::true_type) + { + const key_type& __k = this->_M_extract(__v); + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + + if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code)) + return std::make_pair(iterator(__p, _M_buckets + __n), false); + return std::make_pair(_M_insert_bucket(std::forward<_Pair>(__v), + __n, __code), true); + } // Insert v unconditionally. template<typename _Key, typename _Value, typename _Allocator, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, bool __chc, bool __cit, bool __uk> - typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, - __chc, __cit, __uk>::iterator - _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, - _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: - _M_insert(const value_type& __v, std::false_type) - { - std::pair<bool, std::size_t> __do_rehash - = _M_rehash_policy._M_need_rehash(_M_bucket_count, - _M_element_count, 1); - if (__do_rehash.first) - _M_rehash(__do_rehash.second); + template<typename _Pair> + typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + __chc, __cit, __uk>::iterator + _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: + _M_insert(_Pair&& __v, std::false_type) + { + std::pair<bool, std::size_t> __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, 1); + if (__do_rehash.first) + _M_rehash(__do_rehash.second); - const key_type& __k = this->_M_extract(__v); - typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); - size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); + const key_type& __k = this->_M_extract(__v); + typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); + size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); - // First find the node, avoid leaking new_node if compare throws. - _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code); - _Node* __new_node = _M_allocate_node(__v); + // First find the node, avoid leaking new_node if compare throws. + _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code); + _Node* __new_node = _M_allocate_node(std::forward<_Pair>(__v)); - if (__prev) - { - __new_node->_M_next = __prev->_M_next; - __prev->_M_next = __new_node; - } - else - { - __new_node->_M_next = _M_buckets[__n]; - _M_buckets[__n] = __new_node; - if (__n < _M_begin_bucket_index) - _M_begin_bucket_index = __n; - } - this->_M_store_code(__new_node, __code); + if (__prev) + { + __new_node->_M_next = __prev->_M_next; + __prev->_M_next = __new_node; + } + else + { + __new_node->_M_next = _M_buckets[__n]; + _M_buckets[__n] = __new_node; + if (__n < _M_begin_bucket_index) + _M_begin_bucket_index = __n; + } + this->_M_store_code(__new_node, __code); - ++_M_element_count; - return iterator(__new_node, _M_buckets + __n); - } + ++_M_element_count; + return iterator(__new_node, _M_buckets + __n); + } template<typename _Key, typename _Value, typename _Allocator, typename _ExtractKey, typename _Equal, diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index 694d0ff..3d76839 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -56,6 +56,14 @@ namespace __detail return __distance_fw(__first, __last, _Tag()); } + struct _Select1st + { + template<typename _Pair> + const typename _Pair::first_type& + operator()(const _Pair& __pair) const + { return __pair.first; } + }; + // Auxiliary types used for all instantiations of _Hashtable: nodes // and iterators. @@ -497,25 +505,28 @@ namespace __detail // the form pair<T1, T2> and a key extraction policy that returns the // first part of the pair, the hashtable gets a mapped_type typedef. // If it satisfies those criteria and also has unique keys, then it - // also gets an operator[]. + // also gets an operator[]. template<typename _Key, typename _Value, typename _Ex, bool __unique, typename _Hashtable> struct _Map_base { }; template<typename _Key, typename _Pair, typename _Hashtable> - struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable> + struct _Map_base<_Key, _Pair, _Select1st, false, _Hashtable> { typedef typename _Pair::second_type mapped_type; }; template<typename _Key, typename _Pair, typename _Hashtable> - struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable> + struct _Map_base<_Key, _Pair, _Select1st, true, _Hashtable> { typedef typename _Pair::second_type mapped_type; mapped_type& operator[](const _Key& __k); + mapped_type& + operator[](_Key&& __k); + // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 761. unordered_map needs an at() member function. mapped_type& @@ -526,9 +537,9 @@ namespace __detail }; template<typename _Key, typename _Pair, typename _Hashtable> - typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, + typename _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>::mapped_type& - _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: + _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>:: operator[](const _Key& __k) { _Hashtable* __h = static_cast<_Hashtable*>(this); @@ -545,10 +556,30 @@ namespace __detail } template<typename _Key, typename _Pair, typename _Hashtable> - typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, + typename _Map_base<_Key, _Pair, _Select1st, + true, _Hashtable>::mapped_type& + _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>:: + operator[](_Key&& __k) + { + _Hashtable* __h = static_cast<_Hashtable*>(this); + typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code, + __h->_M_bucket_count); + + typename _Hashtable::_Node* __p = + __h->_M_find_node(__h->_M_buckets[__n], __k, __code); + if (!__p) + return __h->_M_insert_bucket(std::make_pair(std::move(__k), + mapped_type()), + __n, __code)->second; + return (__p->_M_v).second; + } + + template<typename _Key, typename _Pair, typename _Hashtable> + typename _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>::mapped_type& - _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: - at(const _Key& __k) + _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>:: + at(const _Key& __k) { _Hashtable* __h = static_cast<_Hashtable*>(this); typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); @@ -563,10 +594,10 @@ namespace __detail } template<typename _Key, typename _Pair, typename _Hashtable> - const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>, + const typename _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>::mapped_type& - _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: - at(const _Key& __k) const + _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>:: + at(const _Key& __k) const { const _Hashtable* __h = static_cast<const _Hashtable*>(this); typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 08058c1..efd6131 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -41,14 +41,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) bool __cache_hash_code = false> class __unordered_map : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, - std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, __cache_hash_code, false, true> { typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, - std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, @@ -69,7 +69,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __detail::_Mod_range_hashing(), __detail::_Default_ranged_hash(), - __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + __eql, __detail::_Select1st(), __a) { } template<typename _InputIterator> @@ -80,7 +80,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) const allocator_type& __a = allocator_type()) : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), __detail::_Default_ranged_hash(), - __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + __eql, __detail::_Select1st(), __a) { } __unordered_map(initializer_list<value_type> __l, @@ -91,7 +91,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) : _Base(__l.begin(), __l.end(), __n, __hf, __detail::_Mod_range_hashing(), __detail::_Default_ranged_hash(), - __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + __eql, __detail::_Select1st(), __a) { } __unordered_map& @@ -111,7 +111,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) class __unordered_multimap : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, - std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, @@ -119,7 +119,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) { typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, - std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, + __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, @@ -140,7 +140,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __detail::_Mod_range_hashing(), __detail::_Default_ranged_hash(), - __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + __eql, __detail::_Select1st(), __a) { } @@ -152,7 +152,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) const allocator_type& __a = allocator_type()) : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), __detail::_Default_ranged_hash(), - __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + __eql, __detail::_Select1st(), __a) { } __unordered_multimap(initializer_list<value_type> __l, @@ -163,7 +163,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) : _Base(__l.begin(), __l.end(), __n, __hf, __detail::_Mod_range_hashing(), __detail::_Default_ranged_hash(), - __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) + __eql, __detail::_Select1st(), __a) { } __unordered_multimap& diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 2e2f912..6f37e04 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -190,6 +190,28 @@ namespace __debug return iterator(__res.first, this); } + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + std::pair<iterator, bool> + insert(_Pair&& __obj) + { + typedef std::pair<typename _Base::iterator, bool> __pair_type; + __pair_type __res = _Base::insert(std::forward<_Pair>(__obj)); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(const_iterator, _Pair&& __obj) + { + typedef std::pair<typename _Base::iterator, bool> __pair_type; + __pair_type __res = _Base::insert(std::forward<_Pair>(__obj)); + return iterator(__res.first, this); + } + void insert(std::initializer_list<value_type> __l) { _Base::insert(__l); } @@ -444,6 +466,20 @@ namespace __debug insert(const_iterator, const value_type& __obj) { return iterator(_Base::insert(__obj), this); } + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(_Pair&& __obj) + { return iterator(_Base::insert(std::forward<_Pair>(__obj)), this); } + + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(const_iterator, _Pair&& __obj) + { return iterator(_Base::insert(std::forward<_Pair>(__obj)), this); } + void insert(std::initializer_list<value_type> __l) { _Base::insert(__l); } diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index ea90c675..1d42905 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -190,6 +190,22 @@ namespace __debug return iterator(__res.first, this); } + std::pair<iterator, bool> + insert(value_type&& __obj) + { + typedef std::pair<typename _Base::iterator, bool> __pair_type; + __pair_type __res = _Base::insert(std::move(__obj)); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + insert(const_iterator, value_type&& __obj) + { + typedef std::pair<typename _Base::iterator, bool> __pair_type; + __pair_type __res = _Base::insert(std::move(__obj)); + return iterator(__res.first, this); + } + void insert(std::initializer_list<value_type> __l) { _Base::insert(__l); } @@ -440,6 +456,14 @@ namespace __debug insert(const_iterator, const value_type& __obj) { return iterator(_Base::insert(__obj), this); } + iterator + insert(value_type&& __obj) + { return iterator(_Base::insert(std::move(__obj)), this); } + + iterator + insert(const_iterator, value_type&& __obj) + { return iterator(_Base::insert(std::move(__obj)), this); } + void insert(std::initializer_list<value_type> __l) { _Base::insert(__l); } diff --git a/libstdc++-v3/include/profile/unordered_map b/libstdc++-v3/include/profile/unordered_map index 2dec1f2..18563d8 100644 --- a/libstdc++-v3/include/profile/unordered_map +++ b/libstdc++-v3/include/profile/unordered_map @@ -191,6 +191,31 @@ namespace __profile return __res; } + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + std::pair<iterator, bool> + insert(_Pair&& __obj) + { + size_type __old_size = _Base::bucket_count(); + std::pair<iterator, bool> __res + = _Base::insert(std::forward<_Pair>(__obj)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(const_iterator __iter, _Pair&& __v) + { + size_type __old_size = _Base::bucket_count(); + iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + template<typename _InputIter> void insert(_InputIter __first, _InputIter __last) @@ -420,11 +445,35 @@ namespace __profile insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); - iterator __res =_Base::insert(__iter, __v); + iterator __res = _Base::insert(__iter, __v); _M_profile_resize(__old_size, _Base::bucket_count()); return __res; } + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(_Pair&& __obj) + { + size_type __old_size = _Base::bucket_count(); + iterator __res = _Base::insert(std::forward<_Pair>(__obj)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + + template<typename _Pair, typename = typename + std::enable_if<std::is_convertible<_Pair, + value_type>::value>::type> + iterator + insert(const_iterator __iter, _Pair&& __v) + { + size_type __old_size = _Base::bucket_count(); + iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + template<typename _InputIter> void insert(_InputIter __first, _InputIter __last) diff --git a/libstdc++-v3/include/profile/unordered_set b/libstdc++-v3/include/profile/unordered_set index 2dade092..f46cf5c 100644 --- a/libstdc++-v3/include/profile/unordered_set +++ b/libstdc++-v3/include/profile/unordered_set @@ -174,7 +174,7 @@ namespace __profile std::pair<iterator, bool> insert(const value_type& __obj) { - size_type __old_size = _Base::bucket_count(); + size_type __old_size = _Base::bucket_count(); std::pair<iterator, bool> __res = _Base::insert(__obj); _M_profile_resize(__old_size, _Base::bucket_count()); return __res; @@ -189,6 +189,24 @@ namespace __profile return __res; } + std::pair<iterator, bool> + insert(value_type&& __obj) + { + size_type __old_size = _Base::bucket_count(); + std::pair<iterator, bool> __res = _Base::insert(std::move(__obj)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + + iterator + insert(const_iterator __iter, value_type&& __v) + { + size_type __old_size = _Base::bucket_count(); + iterator __res = _Base::insert(__iter, std::move(__v)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + template<typename _InputIter> void insert(_InputIter __first, _InputIter __last) @@ -406,13 +424,31 @@ namespace __profile iterator insert(const_iterator __iter, const value_type& __v) - { + { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); _M_profile_resize(__old_size, _Base::bucket_count()); return __res; } + iterator + insert(value_type&& __obj) + { + size_type __old_size = _Base::bucket_count(); + iterator __res = _Base::insert(std::move(__obj)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + + iterator + insert(const_iterator __iter, value_type&& __v) + { + size_type __old_size = _Base::bucket_count(); + iterator __res = _Base::insert(__iter, std::move(__v)); + _M_profile_resize(__old_size, _Base::bucket_count()); + return __res; + } + template<typename _InputIter> void insert(_InputIter __first, _InputIter __last) diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc index 11fddbb..91f5879 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc @@ -29,25 +29,24 @@ void test01() bool test __attribute__((unused)) = true; typedef std::unordered_map<std::string, int> Map; - typedef std::pair<const std::string, int> Pair; Map m; - VERIFY(m.empty()); + VERIFY( m.empty() ); m["red"] = 17; - VERIFY(m.size() == 1); - VERIFY(m.begin()->first == "red"); - VERIFY(m.begin()->second == 17); - VERIFY(m["red"] == 17); + VERIFY( m.size() == 1 ); + VERIFY( m.begin()->first == "red" ); + VERIFY( m.begin()->second == 17 ); + VERIFY( m["red"] == 17 ); m["blue"] = 9; - VERIFY(m.size() == 2); - VERIFY(m["blue"] == 9); + VERIFY( m.size() == 2 ); + VERIFY( m["blue"] == 9 ); m["red"] = 5; - VERIFY(m.size() == 2); - VERIFY(m["red"] == 5); - VERIFY(m["blue"] == 9); + VERIFY( m.size() == 2 ); + VERIFY( m["red"] == 5 ); + VERIFY( m["blue"] == 9 ); } int main() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax_move.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax_move.cc new file mode 100644 index 0000000..b0729e3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax_move.cc @@ -0,0 +1,59 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Array version of insert + +#include <iterator> +#include <unordered_map> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_map<rvalstruct, rvalstruct> Map; + + Map m; + VERIFY( m.empty() ); + + m[rvalstruct(1)] = rvalstruct(17); + VERIFY( m.size() == 1 ); + VERIFY( (m.begin()->first).val == 1 ); + VERIFY( (m.begin()->second).val == 17 ); + VERIFY( m[rvalstruct(1)].val == 17 ); + + m[rvalstruct(2)] = rvalstruct(9); + VERIFY( m.size() == 2 ); + VERIFY( m[rvalstruct(2)].val == 9 ); + + m[rvalstruct(1)] = rvalstruct(5); + VERIFY( m.size() == 2 ); + VERIFY( m[rvalstruct(1)].val == 5 ); + VERIFY( m[rvalstruct(2)].val == 9 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-1.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-1.cc new file mode 100644 index 0000000..45186ce --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-1.cc @@ -0,0 +1,76 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Single-element insert + +#include <iterator> +#include <unordered_map> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_map<int, rvalstruct> Map; + typedef std::pair<const int, rvalstruct> Pair; + + Map m; + VERIFY( m.empty()); + + std::pair<Map::iterator, bool> p = m.insert(Pair(1, rvalstruct(3))); + VERIFY( p.second ); + VERIFY( m.size() == 1 ); + VERIFY( std::distance(m.begin(), m.end()) == 1 ); + VERIFY( p.first == m.begin() ); + VERIFY( p.first->first == 1 ); + VERIFY( (p.first->second).val == 3 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_map<int, rvalstruct> Map; + typedef std::pair<const int, rvalstruct> Pair; + + Map m; + VERIFY( m.empty() ); + + std::pair<Map::iterator, bool> p1 = m.insert(Pair(2, rvalstruct(3))); + std::pair<Map::iterator, bool> p2 = m.insert(Pair(2, rvalstruct(7))); + + VERIFY( p1.second ); + VERIFY( !p2.second ); + VERIFY( m.size() == 1 ); + VERIFY( p1.first == p2.first ); + VERIFY( p1.first->first == 2 ); + VERIFY( (p2.first->second).val == 3 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-2.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-2.cc new file mode 100644 index 0000000..76b6bba --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-2.cc @@ -0,0 +1,79 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Single-element insert + +#include <iterator> +#include <unordered_map> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_map<rvalstruct, rvalstruct> Map; + typedef std::pair<rvalstruct, rvalstruct> Pair; + + Map m; + VERIFY( m.empty()); + + std::pair<Map::iterator, bool> p = m.insert(Pair(rvalstruct(1), + rvalstruct(3))); + VERIFY( p.second ); + VERIFY( m.size() == 1 ); + VERIFY( std::distance(m.begin(), m.end()) == 1 ); + VERIFY( p.first == m.begin() ); + VERIFY( (p.first->first).val == 1 ); + VERIFY( (p.first->second).val == 3 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_map<rvalstruct, rvalstruct> Map; + typedef std::pair<rvalstruct, rvalstruct> Pair; + + Map m; + VERIFY( m.empty() ); + + std::pair<Map::iterator, bool> p1 = m.insert(Pair(rvalstruct(2), + rvalstruct(3))); + std::pair<Map::iterator, bool> p2 = m.insert(Pair(rvalstruct(2), + rvalstruct(7))); + + VERIFY( p1.second ); + VERIFY( !p2.second ); + VERIFY( m.size() == 1 ); + VERIFY( p1.first == p2.first ); + VERIFY( (p1.first->first).val == 2 ); + VERIFY( (p2.first->second).val == 3 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-1.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-1.cc new file mode 100644 index 0000000..4c93306 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-1.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Single-element insert + +#include <iterator> +#include <unordered_map> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_multimap<int, rvalstruct> Map; + typedef std::pair<const int, rvalstruct> Pair; + + Map m; + VERIFY( m.empty() ); + + Map::iterator i = m.insert(Pair(1, rvalstruct(3))); + VERIFY( m.size() == 1 ); + VERIFY( std::distance(m.begin(), m.end()) == 1 ); + VERIFY( i == m.begin() ); + VERIFY( i->first == 1 ); + VERIFY( (i->second).val == 3 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_multimap<int, rvalstruct> Map; + typedef std::pair<const int, rvalstruct> Pair; + + Map m; + VERIFY( m.empty() ); + + m.insert(Pair(2, rvalstruct(3))); + m.insert(Pair(2, rvalstruct(7))); + + VERIFY( m.size() == 2 ); + VERIFY( std::distance(m.begin(), m.end()) == 2 ); + + Map::iterator i1 = m.begin(); + Map::iterator i2 = i1; + ++i2; + + VERIFY( i1->first == 2 ); + VERIFY( i2->first == 2 ); + VERIFY( ((i1->second).val == 3 && (i2->second).val == 7) + || ((i1->second).val == 7 && (i2->second).val == 3) ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-2.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-2.cc new file mode 100644 index 0000000..e9008b4 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-2.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Single-element insert + +#include <iterator> +#include <unordered_map> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_multimap<rvalstruct, rvalstruct> Map; + typedef std::pair<rvalstruct, rvalstruct> Pair; + + Map m; + VERIFY( m.empty() ); + + Map::iterator i = m.insert(Pair(rvalstruct(1), rvalstruct(3))); + VERIFY( m.size() == 1 ); + VERIFY( std::distance(m.begin(), m.end()) == 1 ); + VERIFY( i == m.begin() ); + VERIFY( (i->first).val == 1 ); + VERIFY( (i->second).val == 3 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_multimap<rvalstruct, rvalstruct> Map; + typedef std::pair<rvalstruct, rvalstruct> Pair; + + Map m; + VERIFY( m.empty() ); + + m.insert(Pair(rvalstruct(2), rvalstruct(3))); + m.insert(Pair(rvalstruct(2), rvalstruct(7))); + + VERIFY( m.size() == 2 ); + VERIFY( std::distance(m.begin(), m.end()) == 2 ); + + Map::iterator i1 = m.begin(); + Map::iterator i2 = i1; + ++i2; + + VERIFY( (i1->first).val == 2 ); + VERIFY( (i2->first).val == 2 ); + VERIFY( ((i1->second).val == 3 && (i2->second).val == 7) + || ((i1->second).val == 7 && (i2->second).val == 3) ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single_move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single_move.cc new file mode 100644 index 0000000..14b8e16 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single_move.cc @@ -0,0 +1,71 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Single-element insert + +#include <iterator> +#include <unordered_set> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_multiset<rvalstruct> Set; + Set s; + VERIFY( s.empty() ); + + Set::iterator i = s.insert(rvalstruct(1)); + VERIFY( s.size() == 1 ); + VERIFY( std::distance(s.begin(), s.end()) == 1 ); + VERIFY( i == s.begin() ); + VERIFY( (*i).val == 1 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_multiset<rvalstruct> Set; + Set s; + VERIFY( s.empty() ); + + s.insert(rvalstruct(2)); + Set::iterator i = s.insert(rvalstruct(2)); + VERIFY( s.size() == 2 ); + VERIFY( std::distance(s.begin(), s.end()) == 2 ); + VERIFY( (*i).val == 2 ); + + Set::iterator i2 = s.begin(); + ++i2; + VERIFY( i == s.begin() || i == i2 ); + VERIFY( (*(s.begin())).val == 2 && (*i2).val == 2 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single_move.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single_move.cc new file mode 100644 index 0000000..0b9ad17 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single_move.cc @@ -0,0 +1,69 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-10-27 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// Single-element insert + +#include <iterator> +#include <unordered_set> +#include <testsuite_hooks.h> +#include <testsuite_rvalref.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_set<rvalstruct> Set; + Set s; + VERIFY( s.empty() ); + + std::pair<Set::iterator, bool> p = s.insert(rvalstruct(1)); + VERIFY( p.second ); + VERIFY( s.size() == 1 ); + VERIFY( std::distance(s.begin(), s.end()) == 1 ); + VERIFY( p.first == s.begin() ); + VERIFY( (*p.first).val == 1 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::rvalstruct; + + typedef std::unordered_set<rvalstruct> Set; + Set s; + VERIFY( s.empty() ); + + std::pair<Set::iterator, bool> p1 = s.insert(rvalstruct(2)); + std::pair<Set::iterator, bool> p2 = s.insert(rvalstruct(2)); + VERIFY( p1.second ); + VERIFY( !p2.second ); + VERIFY( s.size() == 1 ); + VERIFY( p1.first == p2.first ); + VERIFY( (*p1.first).val == 2 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/util/testsuite_rvalref.h b/libstdc++-v3/testsuite/util/testsuite_rvalref.h index b44d6dd..5610b77 100644 --- a/libstdc++-v3/testsuite/util/testsuite_rvalref.h +++ b/libstdc++-v3/testsuite/util/testsuite_rvalref.h @@ -1,7 +1,8 @@ // -*- C++ -*- // Testing utilities for the rvalue reference. // -// Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -27,35 +28,30 @@ namespace __gnu_test { - // This class is designed to test libstdc++'s template-based rvalue - // reference support. It should fail at compile-time if there is an attempt - // to copy it (although see note just below). - class rvalstruct + // This class is designed to test libstdc++'s template-based rvalue + // reference support. It should fail at compile-time if there is an + // attempt to copy it. + struct rvalstruct { - bool - operator=(const rvalstruct&); - - rvalstruct(const rvalstruct&); - - public: int val; bool valid; - rvalstruct() : valid(false) + rvalstruct() : val(0), valid(true) { } rvalstruct(int inval) : val(inval), valid(true) { } - + rvalstruct& operator=(int newval) { - VERIFY(valid == false); - val = newval; + val = newval; valid = true; return *this; } + rvalstruct(const rvalstruct&) = delete; + rvalstruct(rvalstruct&& in) { VERIFY(in.valid == true); @@ -65,6 +61,9 @@ namespace __gnu_test } rvalstruct& + operator=(const rvalstruct&) = delete; + + rvalstruct& operator=(rvalstruct&& in) { VERIFY(in.valid == true); @@ -75,11 +74,11 @@ namespace __gnu_test } }; - bool + inline bool operator==(const rvalstruct& lhs, const rvalstruct& rhs) { return lhs.val == rhs.val; } - bool + inline bool operator<(const rvalstruct& lhs, const rvalstruct& rhs) { return lhs.val < rhs.val; } @@ -156,15 +155,15 @@ namespace __gnu_test int copycounter::copycount = 0; - bool + inline bool operator==(const copycounter& lhs, const copycounter& rhs) { return lhs.val == rhs.val; } - bool + inline bool operator<(const copycounter& lhs, const copycounter& rhs) { return lhs.val < rhs.val; } - void + inline void swap(copycounter& lhs, copycounter& rhs) { VERIFY(lhs.valid && rhs.valid); @@ -175,4 +174,21 @@ namespace __gnu_test } // namespace __gnu_test +namespace std +{ + template<typename _Tp> struct hash; + + /// std::hash specialization for type_index. + template<> + struct hash<__gnu_test::rvalstruct> + { + typedef size_t result_type; + typedef __gnu_test::rvalstruct argument_type; + + size_t + operator()(const __gnu_test::rvalstruct& __rvs) const + { return __rvs.val; } + }; +} + #endif // _GLIBCXX_TESTSUITE_TR1_H |