re PR libstdc++/44436 ([C++0x] Implement emplace* in associative containers)

2012-09-24  François Dumont  <fdumont@gcc.gnu.org>

	PR libstdc++/44436
	* include/bits/stl_tree.h
	(_Rb_tree<>::_M_insert_): Take _Base_ptr rather than
	_Const_Base_ptr.
	(_Rb_tree<>::_M_insert_node): New.
	(_Rb_tree<>::_M_get_insert_unique_pos): New, search code of
	_M_insert_unique method.
	(_Rb_tree<>::_M_insert_unique): Use latter.
	(_Rb_tree<>::_M_emplace_unique): New, likewise.
	(_Rb_tree<>::_M_get_insert_equal_pos): New, search code of
	_M_insert_equal method.
	(_Rb_tree<>::_M_insert_equal): Use latter.
	(_Rb_tree<>::_M_emplace_equal): New, likewise.
	(_Rb_tree<>::_M_get_insert_hint_unique_pos): New, search code of
	_M_insert_unique_ method.
	(_Rb_tree<>::_M_insert_unique_): Use latter.
	(_Rb_tree<>::_M_emplace_hint_unique): New, likewise.
	(_Rb_tree<>::_M_get_insert_hint_equal_pos): New, search code of
	_M_insert_equal_ method.
	(_Rb_tree<>::_M_insert_equal_): Use latter.
	(_Rb_tree<>::_M_emplace_hint_equal): New, likewise.
	(_Rb_tree<>::_M_insert_lower): Remove first _Base_ptr parameter,
	useless as always null.
	* include/bits/stl_map.h: Include <tuple> in C++11.
	(map<>::operator[](const key_type&)): Use
	_Rb_tree<>::_M_emplace_hint_unique in C++11.
	(map<>::operator[](key_type&&)): Likewise.
	(map<>::emplace): New.
	(map<>::emplace_hint): New.
	* include/bits/stl_multimap.h (multimap<>::emplace): New.
	(multimap<>::emplace_hint): New.
	* include/bits/stl_set.h (set<>::emplace): New.
	(set<>::emplace_hint): New.
	* include/bits/stl_multiset.h (multiset<>::emplace): New.
	(multiset<>::emplace_hint): New.
	* include/debug/map.h (std::__debug::map<>::emplace): New.
	(std::__debug::map<>::emplace_hint): New.
	* include/debug/multimap.h (std::__debug::multimap<>::emplace):
	New.
	(std::__debug::multimap<>::emplace_hint): New.
	* include/debug/set.h (std::__debug::set<>::emplace): New.
	(std::__debug::set<>::emplace_hint): New.
	* include/debug/multiset.h (std::__debug::multiset<>::emplace):
	New.
	(std::__debug::multiset<>::emplace_hint): New.
	* include/profile/map.h (std::__profile::map<>::emplace): New.
	(std::__profile::map<>::emplace_hint): New.
	* include/profile/multimap.h (std::__profile::multimap<>::emplace):
	New.
	(std::__profile::multimap<>::emplace_hint): New.
	* include/profile/set.h (std::__profile::set<>::emplace): New.
	(std::__profile::set<>::emplace_hint): New.
	* include/profile/multiset.h (std::__profile::multiset<>::emplace):
	New.
	(std::__profile::multiset<>::emplace_hint): New.
	* testsuite/util/testsuite_container_traits.h: Signal that emplace
	and emplace_hint are available on std::map, std::multimap,
	std::set and std::multiset in C++11.
	* testsuite/23_containers/map/operators/2.cc: New.
	* testsuite/23_containers/map/modifiers/emplace/1.cc: New.
	* testsuite/23_containers/multimap/modifiers/emplace/1.cc: New.
	* testsuite/23_containers/set/modifiers/emplace/1.cc: New.
	* testsuite/23_containers/multiset/modifiers/emplace/1.cc: New.

From-SVN: r191679
This commit is contained in:
François Dumont 2012-09-24 19:53:36 +00:00
parent e6fa043b2d
commit 55826ab6d1
20 changed files with 1304 additions and 143 deletions

View file

@ -1,3 +1,69 @@
2012-09-24 François Dumont <fdumont@gcc.gnu.org>
PR libstdc++/44436
* include/bits/stl_tree.h
(_Rb_tree<>::_M_insert_): Take _Base_ptr rather than
_Const_Base_ptr.
(_Rb_tree<>::_M_insert_node): New.
(_Rb_tree<>::_M_get_insert_unique_pos): New, search code of
_M_insert_unique method.
(_Rb_tree<>::_M_insert_unique): Use latter.
(_Rb_tree<>::_M_emplace_unique): New, likewise.
(_Rb_tree<>::_M_get_insert_equal_pos): New, search code of
_M_insert_equal method.
(_Rb_tree<>::_M_insert_equal): Use latter.
(_Rb_tree<>::_M_emplace_equal): New, likewise.
(_Rb_tree<>::_M_get_insert_hint_unique_pos): New, search code of
_M_insert_unique_ method.
(_Rb_tree<>::_M_insert_unique_): Use latter.
(_Rb_tree<>::_M_emplace_hint_unique): New, likewise.
(_Rb_tree<>::_M_get_insert_hint_equal_pos): New, search code of
_M_insert_equal_ method.
(_Rb_tree<>::_M_insert_equal_): Use latter.
(_Rb_tree<>::_M_emplace_hint_equal): New, likewise.
(_Rb_tree<>::_M_insert_lower): Remove first _Base_ptr parameter,
useless as always null.
* include/bits/stl_map.h: Include <tuple> in C++11.
(map<>::operator[](const key_type&)): Use
_Rb_tree<>::_M_emplace_hint_unique in C++11.
(map<>::operator[](key_type&&)): Likewise.
(map<>::emplace): New.
(map<>::emplace_hint): New.
* include/bits/stl_multimap.h (multimap<>::emplace): New.
(multimap<>::emplace_hint): New.
* include/bits/stl_set.h (set<>::emplace): New.
(set<>::emplace_hint): New.
* include/bits/stl_multiset.h (multiset<>::emplace): New.
(multiset<>::emplace_hint): New.
* include/debug/map.h (std::__debug::map<>::emplace): New.
(std::__debug::map<>::emplace_hint): New.
* include/debug/multimap.h (std::__debug::multimap<>::emplace):
New.
(std::__debug::multimap<>::emplace_hint): New.
* include/debug/set.h (std::__debug::set<>::emplace): New.
(std::__debug::set<>::emplace_hint): New.
* include/debug/multiset.h (std::__debug::multiset<>::emplace):
New.
(std::__debug::multiset<>::emplace_hint): New.
* include/profile/map.h (std::__profile::map<>::emplace): New.
(std::__profile::map<>::emplace_hint): New.
* include/profile/multimap.h (std::__profile::multimap<>::emplace):
New.
(std::__profile::multimap<>::emplace_hint): New.
* include/profile/set.h (std::__profile::set<>::emplace): New.
(std::__profile::set<>::emplace_hint): New.
* include/profile/multiset.h (std::__profile::multiset<>::emplace):
New.
(std::__profile::multiset<>::emplace_hint): New.
* testsuite/util/testsuite_container_traits.h: Signal that emplace
and emplace_hint are available on std::map, std::multimap,
std::set and std::multiset in C++11.
* testsuite/23_containers/map/operators/2.cc: New.
* testsuite/23_containers/map/modifiers/emplace/1.cc: New.
* testsuite/23_containers/multimap/modifiers/emplace/1.cc: New.
* testsuite/23_containers/set/modifiers/emplace/1.cc: New.
* testsuite/23_containers/multiset/modifiers/emplace/1.cc: New.
2012-09-24 François Dumont <fdumont@gcc.gnu.org>
* testsuite/performance/23_containers/insert_erase/41975.cc: Use

View file

@ -61,6 +61,7 @@
#include <bits/concept_check.h>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <initializer_list>
#include <tuple>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
@ -461,7 +462,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
if (__i == end() || key_comp()(__k, (*__i).first))
#ifdef __GXX_EXPERIMENTAL_CXX0X__
__i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
std::tuple<const key_type&>(__k),
std::tuple<>());
#else
__i = insert(__i, value_type(__k, mapped_type()));
#endif
return (*__i).second;
}
@ -475,7 +482,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
if (__i == end() || key_comp()(__k, (*__i).first))
__i = insert(__i, std::make_pair(std::move(__k), mapped_type()));
__i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
std::forward_as_tuple(std::move(__k)),
std::tuple<>());
return (*__i).second;
}
#endif
@ -508,6 +517,64 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
// modifiers
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief Attempts to build and insert a std::pair into the %map.
*
* @param __args Arguments used to generate a new pair instance (see
* std::piecewise_contruct for passing arguments to each
* part of the pair constructor).
*
* @return A pair, of which the first element is an iterator that points
* to the possibly inserted pair, and the second is a bool that
* is true if the pair was actually inserted.
*
* This function attempts to build and insert a (key, value) %pair into
* the %map.
* A %map relies on unique keys and thus a %pair is only inserted if its
* first element (the key) is not already present in the %map.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{ return _M_t._M_emplace_unique(std::forward<_Args>(__args)...); }
/**
* @brief Attempts to build and insert a std::pair into the %map.
*
* @param __pos An iterator that serves as a hint as to where the pair
* should be inserted.
* @param __args Arguments used to generate a new pair instance (see
* std::piecewise_contruct for passing arguments to each
* part of the pair constructor).
* @return An iterator that points to the element with key of the
* std::pair built from @a __args (may or may not be that
* std::pair).
*
* This function is not concerned about whether the insertion took place,
* and thus does not return a boolean like the single-argument emplace()
* does.
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* See
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
* for more on @a hinting.
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_unique(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Attempts to insert a std::pair into the %map.

View file

@ -108,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
public:
class value_compare
@ -433,6 +433,59 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_t.max_size(); }
// modifiers
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief Build and insert a std::pair into the %multimap.
*
* @param __args Arguments used to generate a new pair instance (see
* std::piecewise_contruct for passing arguments to each
* part of the pair constructor).
*
* @return An iterator that points to the inserted (key,value) pair.
*
* This function builds and inserts a (key, value) %pair into the
* %multimap.
* Contrary to a std::map the %multimap does not rely on unique keys and
* thus multiple pairs with the same key can be inserted.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{ return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); }
/**
* @brief Builds and inserts a std::pair into the %multimap.
*
* @param __pos An iterator that serves as a hint as to where the pair
* should be inserted.
* @param __args Arguments used to generate a new pair instance (see
* std::piecewise_contruct for passing arguments to each
* part of the pair constructor).
* @return An iterator that points to the inserted (key,value) pair.
*
* This function inserts a (key, value) pair into the %multimap.
* Contrary to a std::map the %multimap does not rely on unique keys and
* thus multiple pairs with the same key can be inserted.
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_equal(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Inserts a std::pair into the %multimap.
* @param __x Pair to be inserted (see std::make_pair for easy creation

View file

@ -1,7 +1,7 @@
// Multiset implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
// 2011 Free Software Foundation, Inc.
// 2011, 2012 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
@ -392,6 +392,54 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ _M_t.swap(__x._M_t); }
// insert/erase
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief Builds and inserts an element into the %multiset.
* @param __args Arguments used to generate the element instance to be
* inserted.
* @return An iterator that points to the inserted element.
*
* This function inserts an element into the %multiset. Contrary
* to a std::set the %multiset does not rely on unique keys and thus
* multiple copies of the same element can be inserted.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{ return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); }
/**
* @brief Builds and inserts an element into the %multiset.
* @param __pos An iterator that serves as a hint as to where the
* element should be inserted.
* @param __args Arguments used to generate the element instance to be
* inserted.
* @return An iterator that points to the inserted element.
*
* This function inserts an element into the %multiset. Contrary
* to a std::set the %multiset does not rely on unique keys and thus
* multiple copies of the same element can be inserted.
*
* Note that the first parameter is only a hint and can potentially
* improve the performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
* for more on @a hinting.
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_equal(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Inserts an element into the %multiset.
* @param __x Element to be inserted.

View file

@ -1,7 +1,7 @@
// Set implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
// 2011 Free Software Foundation, Inc.
// 2011, 2012 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
@ -395,6 +395,55 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ _M_t.swap(__x._M_t); }
// insert/erase
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief Attempts to build and insert an element into the %set.
* @param __args Arguments used to generate an element.
* @return A pair, of which the first element is an iterator that points
* to the possibly inserted element, and the second is a bool
* that is true if the element was actually inserted.
*
* This function attempts to build and insert an element into the %set.
* A %set relies on unique keys and thus an element is only inserted if
* it is not already present in the %set.
*
* Insertion requires logarithmic time.
*/
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{ return _M_t._M_emplace_unique(std::forward<_Args>(__args)...); }
/**
* @brief Attempts to insert an element into the %set.
* @param __pos An iterator that serves as a hint as to where the
* element should be inserted.
* @param __args Arguments used to generate the element to be
* inserted.
* @return An iterator that points to the element with key equivalent to
* the one generated from @a __args (may or may not be the
* element itself).
*
* This function is not concerned about whether the insertion took place,
* and thus does not return a boolean like the single-argument emplace()
* does. Note that the first parameter is only a hint and can
* potentially improve the performance of the insertion process. A bad
* hint would cause no gains in efficiency.
*
* For more on @a hinting, see:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return _M_t._M_emplace_hint_unique(__pos,
std::forward<_Args>(__args)...);
}
#endif
/**
* @brief Attempts to insert an element into the %set.
* @param __x Element to be inserted.

View file

@ -570,27 +570,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
pair<_Base_ptr, _Base_ptr>
_M_get_insert_unique_pos(const key_type& __k);
pair<_Base_ptr, _Base_ptr>
_M_get_insert_equal_pos(const key_type& __k);
pair<_Base_ptr, _Base_ptr>
_M_get_insert_hint_unique_pos(const_iterator __pos,
const key_type& __k);
pair<_Base_ptr, _Base_ptr>
_M_get_insert_hint_equal_pos(const_iterator __pos,
const key_type& __k);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename _Arg>
iterator
_M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __y, _Arg&& __v);
_M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v);
iterator
_M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
template<typename _Arg>
iterator
_M_insert_lower(_Base_ptr __x, _Base_ptr __y, _Arg&& __v);
_M_insert_lower(_Base_ptr __y, _Arg&& __v);
template<typename _Arg>
iterator
_M_insert_equal_lower(_Arg&& __x);
iterator
_M_insert_lower_node(_Base_ptr __p, _Link_type __z);
iterator
_M_insert_equal_lower_node(_Link_type __z);
#else
iterator
_M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __y,
_M_insert_(_Base_ptr __x, _Base_ptr __y,
const value_type& __v);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 233. Insertion hints in associative containers.
iterator
_M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
_M_insert_lower(_Base_ptr __y, const value_type& __v);
iterator
_M_insert_equal_lower(const value_type& __x);
@ -726,6 +749,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Arg>
iterator
_M_insert_equal_(const_iterator __position, _Arg&& __x);
template<typename... _Args>
pair<iterator, bool>
_M_emplace_unique(_Args&&... __args);
template<typename... _Args>
iterator
_M_emplace_equal(_Args&&... __args);
template<typename... _Args>
iterator
_M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
template<typename... _Args>
iterator
_M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
#else
pair<iterator, bool>
_M_insert_unique(const value_type& __x);
@ -967,19 +1006,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, _Arg&& __v)
_M_insert_(_Base_ptr __x, _Base_ptr __p, _Arg&& __v)
#else
_M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v)
_M_insert_(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
#endif
{
bool __insert_left = (__x != 0 || __p == _M_end()
|| _M_impl._M_key_compare(_KeyOfValue()(__v),
|| _M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__p)));
_Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
_Rb_tree_insert_and_rebalance(__insert_left, __z,
const_cast<_Base_ptr>(__p),
_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
this->_M_impl._M_header);
++_M_impl._M_node_count;
return iterator(__z);
@ -993,18 +1031,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_M_insert_lower(_Base_ptr __x, _Base_ptr __p, _Arg&& __v)
_M_insert_lower(_Base_ptr __p, _Arg&& __v)
#else
_M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
_M_insert_lower(_Base_ptr __p, const _Val& __v)
#endif
{
bool __insert_left = (__x != 0 || __p == _M_end()
bool __insert_left = (__p == _M_end()
|| !_M_impl._M_key_compare(_S_key(__p),
_KeyOfValue()(__v)));
_Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
this->_M_impl._M_header);
++_M_impl._M_node_count;
return iterator(__z);
@ -1031,7 +1069,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
_S_left(__x) : _S_right(__x);
}
return _M_insert_lower(__x, __y, _GLIBCXX_FORWARD(_Arg, __v));
return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v));
}
template<typename _Key, typename _Val, typename _KoV,
@ -1262,6 +1300,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr,
typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_get_insert_unique_pos(const key_type& __k)
{
typedef pair<_Base_ptr, _Base_ptr> _Res;
_Link_type __x = _M_begin();
_Link_type __y = _M_end();
bool __comp = true;
while (__x != 0)
{
__y = __x;
__comp = _M_impl._M_key_compare(__k, _S_key(__x));
__x = __comp ? _S_left(__x) : _S_right(__x);
}
iterator __j = iterator(__y);
if (__comp)
{
if (__j == begin())
return _Res(__x, __y);
else
--__j;
}
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
return _Res(__x, __y);
return _Res(__j._M_node, 0);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr,
typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_get_insert_equal_pos(const key_type& __k)
{
typedef pair<_Base_ptr, _Base_ptr> _Res;
_Link_type __x = _M_begin();
_Link_type __y = _M_end();
while (__x != 0)
{
__y = __x;
__x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
_S_left(__x) : _S_right(__x);
}
return _Res(__x, __y);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@ -1276,28 +1367,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_insert_unique(const _Val& __v)
#endif
{
_Link_type __x = _M_begin();
_Link_type __y = _M_end();
bool __comp = true;
while (__x != 0)
{
__y = __x;
__comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x));
__x = __comp ? _S_left(__x) : _S_right(__x);
}
iterator __j = iterator(__y);
if (__comp)
{
if (__j == begin())
return pair<iterator, bool>
(_M_insert_(__x, __y, _GLIBCXX_FORWARD(_Arg, __v)), true);
else
--__j;
}
if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
return pair<iterator, bool>
(_M_insert_(__x, __y, _GLIBCXX_FORWARD(_Arg, __v)), true);
return pair<iterator, bool>(__j, false);
typedef pair<iterator, bool> _Res;
pair<_Base_ptr, _Base_ptr> __res
= _M_get_insert_unique_pos(_KeyOfValue()(__v));
if (__res.second)
return _Res(_M_insert_(__res.first, __res.second,
_GLIBCXX_FORWARD(_Arg, __v)),
true);
return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
@ -1313,15 +1392,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_insert_equal(const _Val& __v)
#endif
{
_Link_type __x = _M_begin();
_Link_type __y = _M_end();
while (__x != 0)
pair<_Base_ptr, _Base_ptr> __res
= _M_get_insert_equal_pos(_KeyOfValue()(__v));
return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v));
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr,
typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_get_insert_hint_unique_pos(const_iterator __position,
const key_type& __k)
{
iterator __pos = __position._M_const_cast();
typedef pair<_Base_ptr, _Base_ptr> _Res;
// end()
if (__pos._M_node == _M_end())
{
__y = __x;
__x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
_S_left(__x) : _S_right(__x);
if (size() > 0
&& _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
return _Res(0, _M_rightmost());
else
return _M_get_insert_unique_pos(__k);
}
return _M_insert_(__x, __y, _GLIBCXX_FORWARD(_Arg, __v));
else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
{
// First, try before...
iterator __before = __pos;
if (__pos._M_node == _M_leftmost()) // begin()
return _Res(_M_leftmost(), _M_leftmost());
else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
{
if (_S_right(__before._M_node) == 0)
return _Res(0, __before._M_node);
else
return _Res(__pos._M_node, __pos._M_node);
}
else
return _M_get_insert_unique_pos(__k);
}
else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
{
// ... then try after.
iterator __after = __pos;
if (__pos._M_node == _M_rightmost())
return _Res(0, _M_rightmost());
else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
{
if (_S_right(__pos._M_node) == 0)
return _Res(0, __pos._M_node);
else
return _Res(__after._M_node, __after._M_node);
}
else
return _M_get_insert_unique_pos(__k);
}
else
// Equivalent keys.
return _Res(__pos._M_node, 0);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
@ -1337,62 +1469,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_insert_unique_(const_iterator __position, const _Val& __v)
#endif
{
pair<_Base_ptr, _Base_ptr> __res
= _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
if (__res.second)
return _M_insert_(__res.first, __res.second,
_GLIBCXX_FORWARD(_Arg, __v));
return iterator(static_cast<_Link_type>(__res.first));
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr,
typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_Base_ptr>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
{
iterator __pos = __position._M_const_cast();
typedef pair<_Base_ptr, _Base_ptr> _Res;
// end()
if (__position._M_node == _M_end())
if (__pos._M_node == _M_end())
{
if (size() > 0
&& _M_impl._M_key_compare(_S_key(_M_rightmost()),
_KeyOfValue()(__v)))
return _M_insert_(0, _M_rightmost(), _GLIBCXX_FORWARD(_Arg, __v));
&& !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
return _Res(0, _M_rightmost());
else
return _M_insert_unique(_GLIBCXX_FORWARD(_Arg, __v)).first;
return _M_get_insert_equal_pos(__k);
}
else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__position._M_node)))
else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
{
// First, try before...
const_iterator __before = __position;
if (__position._M_node == _M_leftmost()) // begin()
return _M_insert_(_M_leftmost(), _M_leftmost(),
_GLIBCXX_FORWARD(_Arg, __v));
else if (_M_impl._M_key_compare(_S_key((--__before)._M_node),
_KeyOfValue()(__v)))
iterator __before = __pos;
if (__pos._M_node == _M_leftmost()) // begin()
return _Res(_M_leftmost(), _M_leftmost());
else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
{
if (_S_right(__before._M_node) == 0)
return _M_insert_(0, __before._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
return _Res(0, __before._M_node);
else
return _M_insert_(__position._M_node,
__position._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
return _Res(__pos._M_node, __pos._M_node);
}
else
return _M_insert_unique(_GLIBCXX_FORWARD(_Arg, __v)).first;
}
else if (_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// ... then try after.
const_iterator __after = __position;
if (__position._M_node == _M_rightmost())
return _M_insert_(0, _M_rightmost(),
_GLIBCXX_FORWARD(_Arg, __v));
else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key((++__after)._M_node)))
{
if (_S_right(__position._M_node) == 0)
return _M_insert_(0, __position._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
else
return _M_insert_(__after._M_node, __after._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
}
else
return _M_insert_unique(_GLIBCXX_FORWARD(_Arg, __v)).first;
return _M_get_insert_equal_pos(__k);
}
else
// Equivalent keys.
return __position._M_const_cast();
{
// ... then try after.
iterator __after = __pos;
if (__pos._M_node == _M_rightmost())
return _Res(0, _M_rightmost());
else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
{
if (_S_right(__pos._M_node) == 0)
return _Res(0, __pos._M_node);
else
return _Res(__after._M_node, __after._M_node);
}
else
return _Res(0, 0);
}
}
template<typename _Key, typename _Val, typename _KeyOfValue,
@ -1408,61 +1546,166 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_insert_equal_(const_iterator __position, const _Val& __v)
#endif
{
// end()
if (__position._M_node == _M_end())
{
if (size() > 0
&& !_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(_M_rightmost())))
return _M_insert_(0, _M_rightmost(),
_GLIBCXX_FORWARD(_Arg, __v));
else
return _M_insert_equal(_GLIBCXX_FORWARD(_Arg, __v));
}
else if (!_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// First, try before...
const_iterator __before = __position;
if (__position._M_node == _M_leftmost()) // begin()
return _M_insert_(_M_leftmost(), _M_leftmost(),
_GLIBCXX_FORWARD(_Arg, __v));
else if (!_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key((--__before)._M_node)))
{
if (_S_right(__before._M_node) == 0)
return _M_insert_(0, __before._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
else
return _M_insert_(__position._M_node,
__position._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
}
else
return _M_insert_equal(_GLIBCXX_FORWARD(_Arg, __v));
}
else
{
// ... then try after.
const_iterator __after = __position;
if (__position._M_node == _M_rightmost())
return _M_insert_(0, _M_rightmost(),
_GLIBCXX_FORWARD(_Arg, __v));
else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node),
_KeyOfValue()(__v)))
{
if (_S_right(__position._M_node) == 0)
return _M_insert_(0, __position._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
else
return _M_insert_(__after._M_node, __after._M_node,
_GLIBCXX_FORWARD(_Arg, __v));
}
else
return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
}
pair<_Base_ptr, _Base_ptr> __res
= _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
if (__res.second)
return _M_insert_(__res.first, __res.second,
_GLIBCXX_FORWARD(_Arg, __v));
return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
{
bool __insert_left = (__x != 0 || __p == _M_end()
|| _M_impl._M_key_compare(_S_key(__z),
_S_key(__p)));
_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
this->_M_impl._M_header);
++_M_impl._M_node_count;
return iterator(__z);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_insert_lower_node(_Base_ptr __p, _Link_type __z)
{
bool __insert_left = (__p == _M_end()
|| !_M_impl._M_key_compare(_S_key(__p),
_S_key(__z)));
_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
this->_M_impl._M_header);
++_M_impl._M_node_count;
return iterator(__z);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_insert_equal_lower_node(_Link_type __z)
{
_Link_type __x = _M_begin();
_Link_type __y = _M_end();
while (__x != 0)
{
__y = __x;
__x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
_S_left(__x) : _S_right(__x);
}
return _M_insert_lower_node(__y, __z);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
template<typename... _Args>
pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::iterator, bool>
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_emplace_unique(_Args&&... __args)
{
_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
__try
{
typedef pair<iterator, bool> _Res;
auto __res = _M_get_insert_unique_pos(_S_key(__z));
if (__res.second)
return _Res(_M_insert_node(__res.first, __res.second, __z), true);
_M_destroy_node(__z);
return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
}
__catch(...)
{
_M_destroy_node(__z);
__throw_exception_again;
}
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
template<typename... _Args>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_emplace_equal(_Args&&... __args)
{
_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
__try
{
auto __res = _M_get_insert_equal_pos(_S_key(__z));
return _M_insert_node(__res.first, __res.second, __z);
}
__catch(...)
{
_M_destroy_node(__z);
__throw_exception_again;
}
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
template<typename... _Args>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
{
_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
__try
{
auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
if (__res.second)
return _M_insert_node(__res.first, __res.second, __z);
_M_destroy_node(__z);
return iterator(static_cast<_Link_type>(__res.first));
}
__catch(...)
{
_M_destroy_node(__z);
__throw_exception_again;
}
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
template<typename... _Args>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
_M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
{
_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
__try
{
auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
if (__res.second)
return _M_insert_node(__res.first, __res.second, __z);
return _M_insert_equal_lower_node(__z);
}
__catch(...)
{
_M_destroy_node(__z);
__throw_exception_again;
}
}
#endif
template<typename _Key, typename _Val, typename _KoV,
typename _Cmp, typename _Alloc>
template<class _II>

View file

@ -203,6 +203,27 @@ namespace __debug
using _Base::at;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{
auto __res = _Base::emplace(std::forward<_Args>(__args)...);
return std::pair<iterator, bool>(iterator(__res.first, this),
__res.second);
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
__glibcxx_check_insert(__pos);
return iterator(_Base::emplace_hint(__pos.base(),
std::forward<_Args>(__args)...),
this);
}
#endif
std::pair<iterator, bool>
insert(const value_type& __x)
{

View file

@ -195,6 +195,25 @@ namespace __debug
using _Base::max_size;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{
return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
__glibcxx_check_insert(__pos);
return iterator(_Base::emplace_hint(__pos.base(),
std::forward<_Args>(__args)...),
this);
}
#endif
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x), this); }

View file

@ -194,6 +194,25 @@ namespace __debug
using _Base::max_size;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{
return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
__glibcxx_check_insert(__pos);
return iterator(_Base::emplace_hint(__pos.base(),
std::forward<_Args>(__args)...),
this);
}
#endif
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x), this); }

View file

@ -194,6 +194,27 @@ namespace __debug
using _Base::max_size;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{
auto __res = _Base::emplace(std::forward<_Args>(__args)...);
return std::pair<iterator, bool>(iterator(__res.first, this),
__res.second);
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
__glibcxx_check_insert(__pos);
return iterator(_Base::emplace_hint(__pos.base(),
std::forward<_Args>(__args)...),
this);
}
#endif
std::pair<iterator, bool>
insert(const value_type& __x)
{

View file

@ -236,6 +236,29 @@ namespace __profile
}
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{
__profcxx_map_to_unordered_map_insert(this, size(), 1);
auto __res = _Base::emplace(std::forward<_Args>(__args)...);
return std::pair<iterator, bool>(iterator(__res.first),
__res.second);
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
size_type size_before = size();
auto __res = _Base::emplace_hint(__pos.base(),
std::forward<_Args>(__args)...));
__profcxx_map_to_unordered_map_insert(this, size_before,
size() - size_before);
}
#endif
std::pair<iterator, bool>
insert(const value_type& __x)
{
@ -282,7 +305,7 @@ namespace __profile
{
size_type size_before = size();
iterator __i = iterator(_Base::insert(__position, __x));
__profcxx_map_to_unordered_map_insert(this, size_before,
__profcxx_map_to_unordered_map_insert(this, size_before,
size() - size_before);
return __i;
}

View file

@ -180,6 +180,23 @@ namespace __profile
using _Base::max_size;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{
return iterator(_Base::emplace(std::forward<_Args>(__args)...));
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return iterator(_Base::emplace_hint(__pos,
std::forward<_Args>(__args)...));
}
#endif
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x)); }

View file

@ -180,6 +180,21 @@ namespace __profile
using _Base::max_size;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
iterator
emplace(_Args&&... __args)
{ return iterator(_Base::emplace(std::forward<_Args>(__args)...)); }
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return iterator(_Base::emplace_hint(__pos,
std::forward<_Args>(__args)...));
}
#endif
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x)); }

View file

@ -180,6 +180,25 @@ namespace __profile
using _Base::max_size;
// modifiers:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
std::pair<iterator, bool>
emplace(_Args&&... __args)
{
auto __res = _Base::emplace(std::forward<_Args>(__args)...);
return std::pair<iterator, bool>(iterator(__res.first),
__res.second);
}
template<typename... _Args>
iterator
emplace_hint(const_iterator __pos, _Args&&... __args)
{
return iterator(_Base::emplace_hint(__pos,
std::forward<_Args>(__args)...));
}
#endif
std::pair<iterator, bool>
insert(const value_type& __x)
{

View file

@ -0,0 +1,114 @@
// { dg-options "-std=c++11" }
// Copyright (C) 2012 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/>.
#include <utility>
#include <tuple>
#include <vector>
#include <map>
#include <testsuite_hooks.h>
class PathPoint
{
public:
PathPoint(char t, const std::vector<double>& c)
: type(t), coords(c) { }
PathPoint(char t, std::vector<double>&& c)
: type(t), coords(std::move(c)) { }
char getType() const { return type; }
const std::vector<double>& getCoords() const { return coords; }
private:
char type;
std::vector<double> coords;
};
bool test __attribute__((unused)) = true;
void test01()
{
typedef std::map<char, std::vector<double>> Map;
Map m;
std::vector<double> coord1 = { 0.0, 1.0, 2.0 };
auto ret = m.emplace('a', coord1);
VERIFY( ret.second );
VERIFY( m.size() == 1 );
VERIFY( ret.first->first == 'a' );
coord1[0] = 3.0;
ret = m.emplace('a', coord1);
VERIFY( !ret.second );
VERIFY( m.size() == 1 );
VERIFY( ret.first->first == 'a' );
VERIFY( ret.first->second[0] == 0.0 );
auto it = m.emplace_hint(m.begin(), 'b', coord1);
VERIFY( it != m.end() );
VERIFY( it->first == 'b' );
VERIFY( it->second[0] == 3.0 );
double *px = &coord1[0];
ret = m.emplace('c', std::move(coord1));
VERIFY( ret.second );
VERIFY( ret.first->first == 'c' );
VERIFY( &(ret.first->second[0]) == px );
}
void test02()
{
using namespace std;
typedef map<char, PathPoint> Map;
Map m;
vector<double> coord1 = { 0.0, 1.0, 2.0 };
auto ret = m.emplace(piecewise_construct,
make_tuple('a'), make_tuple('a', coord1));
VERIFY( ret.second );
VERIFY( m.size() == 1 );
VERIFY( ret.first->first == 'a' );
coord1[0] = 3.0;
ret = m.emplace(piecewise_construct,
make_tuple('a'), make_tuple( 'b', coord1));
VERIFY( !ret.second );
VERIFY( m.size() == 1 );
VERIFY( ret.first->first == 'a' );
VERIFY( ret.first->second.getCoords()[0] == 0.0 );
auto it = m.emplace_hint(m.begin(), piecewise_construct,
make_tuple('b'), make_tuple('c', coord1));
VERIFY( it != m.end() );
VERIFY( it->first == 'b' );
VERIFY( it->second.getCoords()[0] == 3.0 );
double *px = &coord1[0];
ret = m.emplace(piecewise_construct,
make_tuple('c'), make_tuple('d', move(coord1)));
VERIFY( ret.second );
VERIFY( ret.first->first == 'c' );
VERIFY( &(ret.first->second.getCoords()[0]) == px );
}
int main()
{
test01();
test02();
return 0;
}

View file

@ -0,0 +1,87 @@
// Copyright (C) 2012 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/>.
// This test verifies that the value type of a map need not be default copyable.
// { dg-options "-std=c++11" }
#include <map>
#include <testsuite_hooks.h>
#include <testsuite_rvalref.h>
#include <testsuite_counter_type.h>
struct Mapped
{
Mapped() = default;
explicit Mapped(const Mapped&) = default;
};
struct DefaultConstructibleType
{
int val;
DefaultConstructibleType() : val(123)
{}
DefaultConstructibleType(const DefaultConstructibleType&) = delete;
DefaultConstructibleType(DefaultConstructibleType&&) = delete;
DefaultConstructibleType& operator=(int x)
{
val = x;
return *this;
}
};
void test01()
{
bool test __attribute__((unused)) = true;
using __gnu_test::rvalstruct;
using __gnu_test::counter_type;
std::map<int, Mapped> m1;
m1[0] = Mapped();
std::map<int, rvalstruct> m2;
m2[0] = rvalstruct(13);
std::map<int, DefaultConstructibleType> m3;
VERIFY( m3[0].val == 123 );
VERIFY( m3.size() == 1 );
m3[0] = 2;
VERIFY( m3[0].val == 2 );
std::map<counter_type, int> m4;
VERIFY( m4[counter_type(1)] == 0 );
VERIFY( counter_type::specialize_count == 1 );
VERIFY( counter_type::copy_count == 0 );
VERIFY( counter_type::move_count == 1 );
counter_type k(2);
counter_type::reset();
VERIFY( m4[k] == 0 );
VERIFY( counter_type::copy_count == 1 );
VERIFY( counter_type::move_count == 0 );
}
int main()
{
test01();
return 0;
}

View file

@ -0,0 +1,108 @@
// { dg-options "-std=c++11" }
// Copyright (C) 2012 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/>.
#include <tuple>
#include <vector>
#include <map>
#include <testsuite_hooks.h>
class PathPoint
{
public:
PathPoint(char t, const std::vector<double>& c)
: type(t), coords(c) { }
PathPoint(char t, std::vector<double>&& c)
: type(t), coords(std::move(c)) { }
char getType() const { return type; }
const std::vector<double>& getCoords() const { return coords; }
private:
char type;
std::vector<double> coords;
};
bool test __attribute__((unused)) = true;
void test01()
{
typedef std::multimap<char, std::vector<double>> MMap;
MMap mm;
std::vector<double> coord1 = { 0.0, 1.0, 2.0 };
auto it = mm.emplace('a', coord1);
VERIFY( mm.size() == 1 );
VERIFY( it->first == 'a' );
coord1[0] = 3.0;
it = mm.emplace('a', coord1);
VERIFY( mm.size() == 2 );
VERIFY( it->first == 'a' );
VERIFY( it->second[0] == 3.0 );
it = mm.emplace_hint(mm.begin(), 'b', coord1);
VERIFY( it != mm.end() );
VERIFY( it->first == 'b' );
VERIFY( it->second[0] == 3.0 );
double *px = &coord1[0];
it = mm.emplace('c', std::move(coord1));
VERIFY( it->first == 'c' );
VERIFY( &(it->second[0]) == px );
}
void test02()
{
using namespace std;
typedef multimap<char, PathPoint> Map;
Map m;
vector<double> coord1 = { 0.0, 1.0, 2.0 };
auto it = m.emplace(piecewise_construct,
make_tuple('a'), make_tuple('a', coord1));
VERIFY( m.size() == 1 );
VERIFY( it->first == 'a' );
coord1[0] = 3.0;
it = m.emplace(piecewise_construct,
make_tuple('a'), make_tuple( 'b', coord1));
VERIFY( m.size() == 2 );
VERIFY( it->first == 'a' );
VERIFY( it->second.getCoords()[0] == 3.0 );
it = m.emplace_hint(m.begin(), piecewise_construct,
make_tuple('b'), make_tuple('c', coord1));
VERIFY( it != m.end() );
VERIFY( it->first == 'b' );
VERIFY( it->second.getCoords()[0] == 3.0 );
double *px = &coord1[0];
it = m.emplace(piecewise_construct,
make_tuple('c'), make_tuple('d', move(coord1)));
VERIFY( it->first == 'c' );
VERIFY( &(it->second.getCoords()[0]) == px );
}
int main()
{
test01();
test02();
return 0;
}

View file

@ -0,0 +1,79 @@
// { dg-options "-std=c++11" }
// Copyright (C) 2012 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/>.
#include <vector>
#include <set>
#include <testsuite_hooks.h>
class PathPoint
{
public:
PathPoint(char t, const std::vector<double>& c)
: type(t), coords(c) { }
PathPoint(char t, std::vector<double>&& c)
: type(t), coords(std::move(c)) { }
char getType() const { return type; }
const std::vector<double>& getCoords() const { return coords; }
private:
char type;
std::vector<double> coords;
};
struct PathPointLess
{
bool operator() (const PathPoint& __lhs, const PathPoint& __rhs) const
{ return __lhs.getType() < __rhs.getType(); }
};
bool test __attribute__((unused)) = true;
void test01()
{
typedef std::multiset<PathPoint, PathPointLess> Mset;
Mset ms;
std::vector<double> coord1 = { 0.0, 1.0, 2.0 };
auto it = ms.emplace('a', coord1);
VERIFY( ms.size() == 1 );
VERIFY( it->getType() == 'a' );
coord1[0] = 3.0;
it = ms.emplace('a', coord1);
VERIFY( ms.size() == 2 );
VERIFY( it->getType() == 'a' );
VERIFY( it->getCoords()[0] == 3.0 );
it = ms.emplace_hint(ms.begin(), 'b', coord1);
VERIFY( it != ms.end() );
VERIFY( it->getType() == 'b' );
VERIFY( it->getCoords()[0] == 3.0 );
double *px = &coord1[0];
it = ms.emplace('c', std::move(coord1));
VERIFY( ms.size() == 4 );
VERIFY( it->getType() == 'c' );
VERIFY( &(it->getCoords()[0]) == px );
}
int main()
{
test01();
return 0;
}

View file

@ -0,0 +1,81 @@
// { dg-options "-std=c++11" }
// Copyright (C) 2012 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/>.
#include <vector>
#include <set>
#include <testsuite_hooks.h>
class PathPoint
{
public:
PathPoint(char t, const std::vector<double>& c)
: type(t), coords(c) { }
PathPoint(char t, std::vector<double>&& c)
: type(t), coords(std::move(c)) { }
char getType() const { return type; }
const std::vector<double>& getCoords() const { return coords; }
private:
char type;
std::vector<double> coords;
};
struct PathPointLess
{
bool operator() (const PathPoint& __lhs, const PathPoint& __rhs) const
{ return __lhs.getType() < __rhs.getType(); }
};
bool test __attribute__((unused)) = true;
void test01()
{
typedef std::set<PathPoint, PathPointLess> Set;
Set s;
std::vector<double> coord1 = { 0.0, 1.0, 2.0 };
auto ret = s.emplace('a', coord1);
VERIFY( ret.second );
VERIFY( s.size() == 1 );
VERIFY( ret.first->getType() == 'a' );
coord1[0] = 3.0;
ret = s.emplace('a', coord1);
VERIFY( !ret.second );
VERIFY( s.size() == 1 );
VERIFY( ret.first->getType() == 'a' );
VERIFY( ret.first->getCoords()[0] == 0.0 );
auto it = s.emplace_hint(s.begin(), 'b', coord1);
VERIFY( it != s.end() );
VERIFY( it->getType() == 'b' );
VERIFY( it->getCoords()[0] == 3.0 );
double *px = &coord1[0];
ret = s.emplace('c', std::move(coord1));
VERIFY( ret.second );
VERIFY( ret.first->getType() == 'c' );
VERIFY( &(ret.first->getCoords()[0]) == px );
}
int main()
{
test01();
return 0;
}

View file

@ -148,6 +148,9 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
@ -161,6 +164,9 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@ -173,6 +179,9 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@ -185,6 +194,9 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
#endif
};
template<typename _Tp1, typename _Tp2>