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
This commit is contained in:
Paolo Carlini 2010-10-28 16:01:05 +00:00 committed by Paolo Carlini
parent d724c8f0a9
commit fb7342fd6f
17 changed files with 960 additions and 187 deletions

View File

@ -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> 2010-10-27 Jason Merrill <jason@redhat.com>
* include/std/type_traits (is_literal_type): New. * include/std/type_traits (is_literal_type): New.

View File

@ -178,9 +178,10 @@ namespace std
size_type _M_begin_bucket_index; // First non-empty bucket. size_type _M_begin_bucket_index; // First non-empty bucket.
size_type _M_element_count; size_type _M_element_count;
_RehashPolicy _M_rehash_policy; _RehashPolicy _M_rehash_policy;
_Node* template<typename... _Args>
_M_allocate_node(const value_type& __v); _Node*
_M_allocate_node(_Args&&... __args);
void void
_M_deallocate_node(_Node* __n); _M_deallocate_node(_Node* __n);
@ -360,11 +361,27 @@ namespace std
std::pair<const_iterator, const_iterator> std::pair<const_iterator, const_iterator>
equal_range(const key_type& __k) const; equal_range(const key_type& __k) const;
private: // Find, insert and erase helper functions private:
// ??? This dispatching is a workaround for the fact that we don't // Find, insert and erase helper functions
// have partial specialization of member templates; it would be _Node*
// better to just specialize insert on __unique_keys. There may be a _M_find_node(_Node*, const key_type&,
// cleaner workaround. 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, typedef typename std::conditional<__unique_keys,
std::pair<iterator, bool>, std::pair<iterator, bool>,
iterator>::type iterator>::type
@ -376,30 +393,39 @@ namespace std
>::type >::type
_Insert_Conv_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);
iterator
_M_insert(const value_type&, std::false_type);
public:
// Insert and erase
_Insert_Return_Type _Insert_Return_Type
insert(const value_type& __v) insert(const value_type& __v)
{ return _M_insert(__v, std::integral_constant<bool, { return _M_insert(__v, std::integral_constant<bool, __unique_keys>()); }
__unique_keys>()); }
iterator iterator
insert(const_iterator, const value_type& __v) insert(const_iterator, const value_type& __v)
{ return iterator(_Insert_Conv_Type()(this->insert(__v))); } { return _Insert_Conv_Type()(insert(__v)); }
_Insert_Return_Type
insert(value_type&& __v)
{ return _M_insert(std::move(__v),
std::integral_constant<bool, __unique_keys>()); }
iterator
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> template<typename _InputIterator>
void void
@ -438,26 +464,27 @@ namespace std
typename _Allocator, typename _ExtractKey, typename _Equal, typename _Allocator, typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
bool __chc, bool __cit, bool __uk> bool __chc, bool __cit, bool __uk>
typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, template<typename... _Args>
_H1, _H2, _Hash, _RehashPolicy, typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
__chc, __cit, __uk>::_Node* _H1, _H2, _Hash, _RehashPolicy,
_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, __chc, __cit, __uk>::_Node*
_H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
_M_allocate_node(const value_type& __v) _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
{ _M_allocate_node(_Args&&... __args)
_Node* __n = _M_node_allocator.allocate(1); {
__try _Node* __n = _M_node_allocator.allocate(1);
{ __try
_M_node_allocator.construct(__n, __v); {
__n->_M_next = 0; _M_node_allocator.construct(__n, std::forward<_Args>(__args)...);
return __n; __n->_M_next = 0;
} return __n;
__catch(...) }
{ __catch(...)
_M_node_allocator.deallocate(__n, 1); {
__throw_exception_again; _M_node_allocator.deallocate(__n, 1);
} __throw_exception_again;
} }
}
template<typename _Key, typename _Value, template<typename _Key, typename _Value,
typename _Allocator, typename _ExtractKey, typename _Equal, typename _Allocator, typename _ExtractKey, typename _Equal,
@ -871,111 +898,117 @@ namespace std
typename _Allocator, typename _ExtractKey, typename _Equal, typename _Allocator, typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
bool __chc, bool __cit, bool __uk> bool __chc, bool __cit, bool __uk>
typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, template<typename _Pair>
_H1, _H2, _Hash, _RehashPolicy, typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
__chc, __cit, __uk>::iterator _H1, _H2, _Hash, _RehashPolicy,
_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, __chc, __cit, __uk>::iterator
_H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
_M_insert_bucket(const value_type& __v, size_type __n, _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
typename _Hashtable::_Hash_code_type __code) _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, std::pair<bool, std::size_t> __do_rehash
_M_element_count, 1); = _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 if (__do_rehash.first)
// do a rehash if the allocation throws. {
_Node* __new_node = _M_allocate_node(__v); const key_type& __k = this->_M_extract(__v);
__n = this->_M_bucket_index(__k, __code, __do_rehash.second);
}
__try // Allocate the new node before doing the rehash so that we don't
{ // do a rehash if the allocation throws.
if (__do_rehash.first) _Node* __new_node = _M_allocate_node(std::forward<_Pair>(__v));
{
const key_type& __k = this->_M_extract(__v); __try
__n = this->_M_bucket_index(__k, __code, __do_rehash.second); {
if (__do_rehash.first)
_M_rehash(__do_rehash.second); _M_rehash(__do_rehash.second);
}
__new_node->_M_next = _M_buckets[__n]; __new_node->_M_next = _M_buckets[__n];
this->_M_store_code(__new_node, __code); this->_M_store_code(__new_node, __code);
_M_buckets[__n] = __new_node; _M_buckets[__n] = __new_node;
++_M_element_count; ++_M_element_count;
if (__n < _M_begin_bucket_index) if (__n < _M_begin_bucket_index)
_M_begin_bucket_index = __n; _M_begin_bucket_index = __n;
return iterator(__new_node, _M_buckets + __n); return iterator(__new_node, _M_buckets + __n);
} }
__catch(...) __catch(...)
{ {
_M_deallocate_node(__new_node); _M_deallocate_node(__new_node);
__throw_exception_again; __throw_exception_again;
} }
} }
// Insert v if no element with its key is already present. // Insert v if no element with its key is already present.
template<typename _Key, typename _Value, template<typename _Key, typename _Value,
typename _Allocator, typename _ExtractKey, typename _Equal, typename _Allocator, typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
bool __chc, bool __cit, bool __uk> bool __chc, bool __cit, bool __uk>
std::pair<typename _Hashtable<_Key, _Value, _Allocator, template<typename _Pair>
_ExtractKey, _Equal, _H1, std::pair<typename _Hashtable<_Key, _Value, _Allocator,
_H2, _Hash, _RehashPolicy, _ExtractKey, _Equal, _H1,
__chc, __cit, __uk>::iterator, bool> _H2, _Hash, _RehashPolicy,
_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, __chc, __cit, __uk>::iterator, bool>
_H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
_M_insert(const value_type& __v, std::true_type) _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); const key_type& __k = this->_M_extract(__v);
size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); 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)) 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(iterator(__p, _M_buckets + __n), false);
return std::make_pair(_M_insert_bucket(__v, __n, __code), true); return std::make_pair(_M_insert_bucket(std::forward<_Pair>(__v),
} __n, __code), true);
}
// Insert v unconditionally. // Insert v unconditionally.
template<typename _Key, typename _Value, template<typename _Key, typename _Value,
typename _Allocator, typename _ExtractKey, typename _Equal, typename _Allocator, typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
bool __chc, bool __cit, bool __uk> bool __chc, bool __cit, bool __uk>
typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, template<typename _Pair>
_H1, _H2, _Hash, _RehashPolicy, typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
__chc, __cit, __uk>::iterator _H1, _H2, _Hash, _RehashPolicy,
_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, __chc, __cit, __uk>::iterator
_H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
_M_insert(const value_type& __v, std::false_type) _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, std::pair<bool, std::size_t> __do_rehash
_M_element_count, 1); = _M_rehash_policy._M_need_rehash(_M_bucket_count,
if (__do_rehash.first) _M_element_count, 1);
_M_rehash(__do_rehash.second); if (__do_rehash.first)
_M_rehash(__do_rehash.second);
const key_type& __k = this->_M_extract(__v); const key_type& __k = this->_M_extract(__v);
typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k); typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count); size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
// First find the node, avoid leaking new_node if compare throws. // First find the node, avoid leaking new_node if compare throws.
_Node* __prev = _M_find_node(_M_buckets[__n], __k, __code); _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code);
_Node* __new_node = _M_allocate_node(__v); _Node* __new_node = _M_allocate_node(std::forward<_Pair>(__v));
if (__prev) if (__prev)
{ {
__new_node->_M_next = __prev->_M_next; __new_node->_M_next = __prev->_M_next;
__prev->_M_next = __new_node; __prev->_M_next = __new_node;
} }
else else
{ {
__new_node->_M_next = _M_buckets[__n]; __new_node->_M_next = _M_buckets[__n];
_M_buckets[__n] = __new_node; _M_buckets[__n] = __new_node;
if (__n < _M_begin_bucket_index) if (__n < _M_begin_bucket_index)
_M_begin_bucket_index = __n; _M_begin_bucket_index = __n;
} }
this->_M_store_code(__new_node, __code); this->_M_store_code(__new_node, __code);
++_M_element_count; ++_M_element_count;
return iterator(__new_node, _M_buckets + __n); return iterator(__new_node, _M_buckets + __n);
} }
template<typename _Key, typename _Value, template<typename _Key, typename _Value,
typename _Allocator, typename _ExtractKey, typename _Equal, typename _Allocator, typename _ExtractKey, typename _Equal,

View File

@ -56,6 +56,14 @@ namespace __detail
return __distance_fw(__first, __last, _Tag()); 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 // Auxiliary types used for all instantiations of _Hashtable: nodes
// and iterators. // and iterators.
@ -497,25 +505,28 @@ namespace __detail
// the form pair<T1, T2> and a key extraction policy that returns the // 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. // first part of the pair, the hashtable gets a mapped_type typedef.
// If it satisfies those criteria and also has unique keys, then it // 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, template<typename _Key, typename _Value, typename _Ex, bool __unique,
typename _Hashtable> typename _Hashtable>
struct _Map_base { }; struct _Map_base { };
template<typename _Key, typename _Pair, typename _Hashtable> 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; typedef typename _Pair::second_type mapped_type;
}; };
template<typename _Key, typename _Pair, typename _Hashtable> 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; typedef typename _Pair::second_type mapped_type;
mapped_type& mapped_type&
operator[](const _Key& __k); operator[](const _Key& __k);
mapped_type&
operator[](_Key&& __k);
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 761. unordered_map needs an at() member function. // DR 761. unordered_map needs an at() member function.
mapped_type& mapped_type&
@ -526,9 +537,9 @@ namespace __detail
}; };
template<typename _Key, typename _Pair, typename _Hashtable> 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& true, _Hashtable>::mapped_type&
_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>::
operator[](const _Key& __k) operator[](const _Key& __k)
{ {
_Hashtable* __h = static_cast<_Hashtable*>(this); _Hashtable* __h = static_cast<_Hashtable*>(this);
@ -545,10 +556,30 @@ namespace __detail
} }
template<typename _Key, typename _Pair, typename _Hashtable> 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& true, _Hashtable>::mapped_type&
_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>::
at(const _Key& __k) 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, _Select1st, true, _Hashtable>::
at(const _Key& __k)
{ {
_Hashtable* __h = static_cast<_Hashtable*>(this); _Hashtable* __h = static_cast<_Hashtable*>(this);
typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
@ -563,10 +594,10 @@ namespace __detail
} }
template<typename _Key, typename _Pair, typename _Hashtable> 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& true, _Hashtable>::mapped_type&
_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>:: _Map_base<_Key, _Pair, _Select1st, true, _Hashtable>::
at(const _Key& __k) const at(const _Key& __k) const
{ {
const _Hashtable* __h = static_cast<const _Hashtable*>(this); const _Hashtable* __h = static_cast<const _Hashtable*>(this);
typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k); typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);

View File

@ -41,14 +41,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
bool __cache_hash_code = false> bool __cache_hash_code = false>
class __unordered_map class __unordered_map
: public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, : 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, _Hash, __detail::_Mod_range_hashing,
__detail::_Default_ranged_hash, __detail::_Default_ranged_hash,
__detail::_Prime_rehash_policy, __detail::_Prime_rehash_policy,
__cache_hash_code, false, true> __cache_hash_code, false, true>
{ {
typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, 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, _Hash, __detail::_Mod_range_hashing,
__detail::_Default_ranged_hash, __detail::_Default_ranged_hash,
__detail::_Prime_rehash_policy, __detail::_Prime_rehash_policy,
@ -69,7 +69,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__n, __hf, __detail::_Mod_range_hashing(), : _Base(__n, __hf, __detail::_Mod_range_hashing(),
__detail::_Default_ranged_hash(), __detail::_Default_ranged_hash(),
__eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) __eql, __detail::_Select1st(), __a)
{ } { }
template<typename _InputIterator> template<typename _InputIterator>
@ -80,7 +80,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
__detail::_Default_ranged_hash(), __detail::_Default_ranged_hash(),
__eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) __eql, __detail::_Select1st(), __a)
{ } { }
__unordered_map(initializer_list<value_type> __l, __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, : _Base(__l.begin(), __l.end(), __n, __hf,
__detail::_Mod_range_hashing(), __detail::_Mod_range_hashing(),
__detail::_Default_ranged_hash(), __detail::_Default_ranged_hash(),
__eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) __eql, __detail::_Select1st(), __a)
{ } { }
__unordered_map& __unordered_map&
@ -111,7 +111,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
class __unordered_multimap class __unordered_multimap
: public _Hashtable<_Key, std::pair<const _Key, _Tp>, : public _Hashtable<_Key, std::pair<const _Key, _Tp>,
_Alloc, _Alloc,
std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, __detail::_Select1st, _Pred,
_Hash, __detail::_Mod_range_hashing, _Hash, __detail::_Mod_range_hashing,
__detail::_Default_ranged_hash, __detail::_Default_ranged_hash,
__detail::_Prime_rehash_policy, __detail::_Prime_rehash_policy,
@ -119,7 +119,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
{ {
typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, typedef _Hashtable<_Key, std::pair<const _Key, _Tp>,
_Alloc, _Alloc,
std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, __detail::_Select1st, _Pred,
_Hash, __detail::_Mod_range_hashing, _Hash, __detail::_Mod_range_hashing,
__detail::_Default_ranged_hash, __detail::_Default_ranged_hash,
__detail::_Prime_rehash_policy, __detail::_Prime_rehash_policy,
@ -140,7 +140,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__n, __hf, __detail::_Mod_range_hashing(), : _Base(__n, __hf, __detail::_Mod_range_hashing(),
__detail::_Default_ranged_hash(), __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()) const allocator_type& __a = allocator_type())
: _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(), : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
__detail::_Default_ranged_hash(), __detail::_Default_ranged_hash(),
__eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) __eql, __detail::_Select1st(), __a)
{ } { }
__unordered_multimap(initializer_list<value_type> __l, __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, : _Base(__l.begin(), __l.end(), __n, __hf,
__detail::_Mod_range_hashing(), __detail::_Mod_range_hashing(),
__detail::_Default_ranged_hash(), __detail::_Default_ranged_hash(),
__eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a) __eql, __detail::_Select1st(), __a)
{ } { }
__unordered_multimap& __unordered_multimap&

View File

@ -190,6 +190,28 @@ namespace __debug
return iterator(__res.first, this); 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 void
insert(std::initializer_list<value_type> __l) insert(std::initializer_list<value_type> __l)
{ _Base::insert(__l); } { _Base::insert(__l); }
@ -444,6 +466,20 @@ namespace __debug
insert(const_iterator, const value_type& __obj) insert(const_iterator, const value_type& __obj)
{ return iterator(_Base::insert(__obj), this); } { 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 void
insert(std::initializer_list<value_type> __l) insert(std::initializer_list<value_type> __l)
{ _Base::insert(__l); } { _Base::insert(__l); }

View File

@ -190,6 +190,22 @@ namespace __debug
return iterator(__res.first, this); 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 void
insert(std::initializer_list<value_type> __l) insert(std::initializer_list<value_type> __l)
{ _Base::insert(__l); } { _Base::insert(__l); }
@ -440,6 +456,14 @@ namespace __debug
insert(const_iterator, const value_type& __obj) insert(const_iterator, const value_type& __obj)
{ return iterator(_Base::insert(__obj), this); } { 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 void
insert(std::initializer_list<value_type> __l) insert(std::initializer_list<value_type> __l)
{ _Base::insert(__l); } { _Base::insert(__l); }

View File

@ -191,6 +191,31 @@ namespace __profile
return __res; 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> template<typename _InputIter>
void void
insert(_InputIter __first, _InputIter __last) insert(_InputIter __first, _InputIter __last)
@ -420,11 +445,35 @@ namespace __profile
insert(const_iterator __iter, const value_type& __v) insert(const_iterator __iter, const value_type& __v)
{ {
size_type __old_size = _Base::bucket_count(); 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()); _M_profile_resize(__old_size, _Base::bucket_count());
return __res; 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> template<typename _InputIter>
void void
insert(_InputIter __first, _InputIter __last) insert(_InputIter __first, _InputIter __last)

View File

@ -174,7 +174,7 @@ namespace __profile
std::pair<iterator, bool> std::pair<iterator, bool>
insert(const value_type& __obj) 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); std::pair<iterator, bool> __res = _Base::insert(__obj);
_M_profile_resize(__old_size, _Base::bucket_count()); _M_profile_resize(__old_size, _Base::bucket_count());
return __res; return __res;
@ -189,6 +189,24 @@ namespace __profile
return __res; 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> template<typename _InputIter>
void void
insert(_InputIter __first, _InputIter __last) insert(_InputIter __first, _InputIter __last)
@ -406,13 +424,31 @@ namespace __profile
iterator iterator
insert(const_iterator __iter, const value_type& __v) insert(const_iterator __iter, const value_type& __v)
{ {
size_type __old_size = _Base::bucket_count(); 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()); _M_profile_resize(__old_size, _Base::bucket_count());
return __res; 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> template<typename _InputIter>
void void
insert(_InputIter __first, _InputIter __last) insert(_InputIter __first, _InputIter __last)

View File

@ -29,25 +29,24 @@ void test01()
bool test __attribute__((unused)) = true; bool test __attribute__((unused)) = true;
typedef std::unordered_map<std::string, int> Map; typedef std::unordered_map<std::string, int> Map;
typedef std::pair<const std::string, int> Pair;
Map m; Map m;
VERIFY(m.empty()); VERIFY( m.empty() );
m["red"] = 17; m["red"] = 17;
VERIFY(m.size() == 1); VERIFY( m.size() == 1 );
VERIFY(m.begin()->first == "red"); VERIFY( m.begin()->first == "red" );
VERIFY(m.begin()->second == 17); VERIFY( m.begin()->second == 17 );
VERIFY(m["red"] == 17); VERIFY( m["red"] == 17 );
m["blue"] = 9; m["blue"] = 9;
VERIFY(m.size() == 2); VERIFY( m.size() == 2 );
VERIFY(m["blue"] == 9); VERIFY( m["blue"] == 9 );
m["red"] = 5; m["red"] = 5;
VERIFY(m.size() == 2); VERIFY( m.size() == 2 );
VERIFY(m["red"] == 5); VERIFY( m["red"] == 5 );
VERIFY(m["blue"] == 9); VERIFY( m["blue"] == 9 );
} }
int main() int main()

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,7 +1,8 @@
// -*- C++ -*- // -*- C++ -*-
// Testing utilities for the rvalue reference. // 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 // 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 // software; you can redistribute it and/or modify it under the
@ -27,35 +28,30 @@
namespace __gnu_test namespace __gnu_test
{ {
// This class is designed to test libstdc++'s template-based rvalue // This class is designed to test libstdc++'s template-based rvalue
// reference support. It should fail at compile-time if there is an attempt // reference support. It should fail at compile-time if there is an
// to copy it (although see note just below). // attempt to copy it.
class rvalstruct struct rvalstruct
{ {
bool
operator=(const rvalstruct&);
rvalstruct(const rvalstruct&);
public:
int val; int val;
bool valid; bool valid;
rvalstruct() : valid(false) rvalstruct() : val(0), valid(true)
{ } { }
rvalstruct(int inval) : val(inval), valid(true) rvalstruct(int inval) : val(inval), valid(true)
{ } { }
rvalstruct& rvalstruct&
operator=(int newval) operator=(int newval)
{ {
VERIFY(valid == false); val = newval;
val = newval;
valid = true; valid = true;
return *this; return *this;
} }
rvalstruct(const rvalstruct&) = delete;
rvalstruct(rvalstruct&& in) rvalstruct(rvalstruct&& in)
{ {
VERIFY(in.valid == true); VERIFY(in.valid == true);
@ -64,6 +60,9 @@ namespace __gnu_test
valid = true; valid = true;
} }
rvalstruct&
operator=(const rvalstruct&) = delete;
rvalstruct& rvalstruct&
operator=(rvalstruct&& in) operator=(rvalstruct&& in)
{ {
@ -75,11 +74,11 @@ namespace __gnu_test
} }
}; };
bool inline bool
operator==(const rvalstruct& lhs, const rvalstruct& rhs) operator==(const rvalstruct& lhs, const rvalstruct& rhs)
{ return lhs.val == rhs.val; } { return lhs.val == rhs.val; }
bool inline bool
operator<(const rvalstruct& lhs, const rvalstruct& rhs) operator<(const rvalstruct& lhs, const rvalstruct& rhs)
{ return lhs.val < rhs.val; } { return lhs.val < rhs.val; }
@ -156,15 +155,15 @@ namespace __gnu_test
int copycounter::copycount = 0; int copycounter::copycount = 0;
bool inline bool
operator==(const copycounter& lhs, const copycounter& rhs) operator==(const copycounter& lhs, const copycounter& rhs)
{ return lhs.val == rhs.val; } { return lhs.val == rhs.val; }
bool inline bool
operator<(const copycounter& lhs, const copycounter& rhs) operator<(const copycounter& lhs, const copycounter& rhs)
{ return lhs.val < rhs.val; } { return lhs.val < rhs.val; }
void inline void
swap(copycounter& lhs, copycounter& rhs) swap(copycounter& lhs, copycounter& rhs)
{ {
VERIFY(lhs.valid && rhs.valid); VERIFY(lhs.valid && rhs.valid);
@ -175,4 +174,21 @@ namespace __gnu_test
} // 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 #endif // _GLIBCXX_TESTSUITE_TR1_H