diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2018-09-03 15:25:25 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2018-09-03 15:25:25 +0100 |
commit | 83a840a91fb3281f8980eaacdb7b5377778da3bb (patch) | |
tree | 2e92c6147aece7f85ca771a0c202e3d5d84e5e6e | |
parent | bc62e155e412fd2230ec0538e2bef86211d26301 (diff) | |
download | gcc-83a840a91fb3281f8980eaacdb7b5377778da3bb.zip gcc-83a840a91fb3281f8980eaacdb7b5377778da3bb.tar.gz gcc-83a840a91fb3281f8980eaacdb7b5377778da3bb.tar.bz2 |
PR libstdc++/87194 fix range insertion into maps and sets
Since C++11 range insertion and construction of maps and sets from a
pair of iterators only requires that the iterator's value_type is
convertible to the container's value_type (previously it had to be the
same).
This fixes the implementation to meet that relaxed requirement, by
defining a pair of overloads that either insert or emplace, depending on
the iterator's value_type. Instead of adding yet another overload of
_M_insert_unique and _M_insert_equal, the overloads taking iterators are
renamed to _M_insert_range_unique and _M_insert_range_equal.
PR libstdc++/87194
* include/bits/stl_map.h
(map::map(initializer_list<value_type>, const Compare&, const Alloc&))
(map::map(initializer_list<value_type>, const Alloc&))
(map::map(InputIterator, InputIterator, const Alloc&))
(map::map(InputIterator, InputIterator))
(map::map(InputIterator, InputIterator, const Compare&, const Alloc&))
(map::insert(InputIterator, InputIterator)):
Call _M_insert_range_unique instead of _M_insert_unique.
* include/bits/stl_multimap.h
(multimap::multimap(initializer_list<value_type>, const C&, const A&))
(multimap::multimap(initializer_list<value_type>, const A&))
(multimap::multimap(InputIterator, InputIterator, const A&))
(multimap::multimap(InputIterator, InputIterator))
(multimap::multimap(InputIterator, InputIterator, const C&, const A&))
(multimap::insert(InputIterator, InputIterator)): Call
_M_insert_range_equal instead of _M_insert_equal.
* include/bits/stl_multiset.h
(multiset::multiset(InputIterator, InputIterator))
(multiset::multiset(InputIterator, InputIterator, const C&, const A&))
(multiset::multiset(initializer_list<value_type>, const C&, const A&))
(multiset::multiset(initializer_list<value_type>, const A&))
(multiset::multiset(InputIterator, InputIterator, const A&))
(multiset::insert(InputIterator, InputIterator)): Call
_M_insert_range_equal instead of _M_insert_equal.
* include/bits/stl_set.h
(set::set(InputIterator, InputIterator))
(set::set(InputIterator, InputIterator, const Compare&, const Alloc&))
(set::set(initializer_list<value_type>, const Compare&, const Alloc&))
(set::set(initializer_list<value_type>, const Alloc&))
(set::set(InputIterator, InputIterator, const Alloc&))
(set::insert(InputIterator, InputIterator)):
Call _M_insert_range_unique instead of _M_insert_unique.
* include/bits/stl_tree.h
[__cplusplus >= 201103L] (_Rb_tree::__same_value_type): New alias
template for SFINAE constraints.
[__cplusplus >= 201103L] (_Rb_tree::_M_insert_range_unique): Pair of
constrained overloads that either insert or emplace, depending on
iterator's value_type.
[__cplusplus >= 201103L] (_Rb_tree::_M_insert_range_equal): Likewise.
[__cplusplus < 201103L] (_Rb_tree::_M_insert_range_unique)
(_Rb_tree::_M_insert_range_equal): New functions replacing range
versions of _M_insert_unique and _M_insert_equal.
(_Rb_tree::_M_insert_unique(_InputIterator, _InputIterator))
(_Rb_tree::_M_insert_equal(_InputIterator, _InputIterator)): Remove.
* testsuite/23_containers/map/modifiers/insert/87194.cc: New test.
* testsuite/23_containers/multimap/modifiers/insert/87194.cc: New test.
* testsuite/23_containers/multiset/modifiers/insert/87194.cc: New test.
* testsuite/23_containers/set/modifiers/insert/87194.cc: New test.
From-SVN: r264060
-rw-r--r-- | libstdc++-v3/ChangeLog | 50 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_map.h | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_multimap.h | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_multiset.h | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_set.h | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_tree.h | 78 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/map/modifiers/insert/87194.cc | 46 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/87194.cc | 46 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/87194.cc | 44 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/set/modifiers/insert/87194.cc | 44 |
10 files changed, 306 insertions, 50 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 763da9e..6a576ba 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,55 @@ 2018-09-03 Jonathan Wakely <jwakely@redhat.com> + PR libstdc++/87194 + * include/bits/stl_map.h + (map::map(initializer_list<value_type>, const Compare&, const Alloc&)) + (map::map(initializer_list<value_type>, const Alloc&)) + (map::map(InputIterator, InputIterator, const Alloc&)) + (map::map(InputIterator, InputIterator)) + (map::map(InputIterator, InputIterator, const Compare&, const Alloc&)) + (map::insert(InputIterator, InputIterator)): + Call _M_insert_range_unique instead of _M_insert_unique. + * include/bits/stl_multimap.h + (multimap::multimap(initializer_list<value_type>, const C&, const A&)) + (multimap::multimap(initializer_list<value_type>, const A&)) + (multimap::multimap(InputIterator, InputIterator, const A&)) + (multimap::multimap(InputIterator, InputIterator)) + (multimap::multimap(InputIterator, InputIterator, const C&, const A&)) + (multimap::insert(InputIterator, InputIterator)): Call + _M_insert_range_equal instead of _M_insert_equal. + * include/bits/stl_multiset.h + (multiset::multiset(InputIterator, InputIterator)) + (multiset::multiset(InputIterator, InputIterator, const C&, const A&)) + (multiset::multiset(initializer_list<value_type>, const C&, const A&)) + (multiset::multiset(initializer_list<value_type>, const A&)) + (multiset::multiset(InputIterator, InputIterator, const A&)) + (multiset::insert(InputIterator, InputIterator)): Call + _M_insert_range_equal instead of _M_insert_equal. + * include/bits/stl_set.h + (set::set(InputIterator, InputIterator)) + (set::set(InputIterator, InputIterator, const Compare&, const Alloc&)) + (set::set(initializer_list<value_type>, const Compare&, const Alloc&)) + (set::set(initializer_list<value_type>, const Alloc&)) + (set::set(InputIterator, InputIterator, const Alloc&)) + (set::insert(InputIterator, InputIterator)): + Call _M_insert_range_unique instead of _M_insert_unique. + * include/bits/stl_tree.h + [__cplusplus >= 201103L] (_Rb_tree::__same_value_type): New alias + template for SFINAE constraints. + [__cplusplus >= 201103L] (_Rb_tree::_M_insert_range_unique): Pair of + constrained overloads that either insert or emplace, depending on + iterator's value_type. + [__cplusplus >= 201103L] (_Rb_tree::_M_insert_range_equal): Likewise. + [__cplusplus < 201103L] (_Rb_tree::_M_insert_range_unique) + (_Rb_tree::_M_insert_range_equal): New functions replacing range + versions of _M_insert_unique and _M_insert_equal. + (_Rb_tree::_M_insert_unique(_InputIterator, _InputIterator)) + (_Rb_tree::_M_insert_equal(_InputIterator, _InputIterator)): Remove. + * testsuite/23_containers/map/modifiers/insert/87194.cc: New test. + * testsuite/23_containers/multimap/modifiers/insert/87194.cc: New test. + * testsuite/23_containers/multiset/modifiers/insert/87194.cc: New test. + * testsuite/23_containers/set/modifiers/insert/87194.cc: New test. + PR libstdc++/78595 * include/bits/stl_map.h (map::insert(_Pair&&)) (map::insert(const_iterator, _Pair&&)): Do emplace instead of insert. diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 6ce9c3e..0a4946c 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -227,7 +227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) - { _M_t._M_insert_unique(__l.begin(), __l.end()); } + { _M_t._M_insert_range_unique(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit @@ -247,14 +247,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Allocator-extended initialier-list constructor. map(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Pair_alloc_type(__a)) - { _M_t._M_insert_unique(__l.begin(), __l.end()); } + { _M_t._M_insert_range_unique(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> map(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Pair_alloc_type(__a)) - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } #endif /** @@ -270,7 +270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> map(_InputIterator __first, _InputIterator __last) : _M_t() - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } /** * @brief Builds a %map from a range. @@ -289,7 +289,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } #if __cplusplus >= 201103L /** @@ -889,7 +889,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } #if __cplusplus > 201402L #define __cpp_lib_map_insertion 201411 diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index d497387..6d5c264 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -224,7 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) - { _M_t._M_insert_equal(__l.begin(), __l.end()); } + { _M_t._M_insert_range_equal(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit @@ -244,14 +244,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Allocator-extended initialier-list constructor. multimap(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Pair_alloc_type(__a)) - { _M_t._M_insert_equal(__l.begin(), __l.end()); } + { _M_t._M_insert_range_equal(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> multimap(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Pair_alloc_type(__a)) - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } #endif /** @@ -266,7 +266,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> multimap(_InputIterator __first, _InputIterator __last) : _M_t() - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } /** * @brief Builds a %multimap from a range. @@ -284,7 +284,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } #if __cplusplus >= 201103L /** @@ -609,7 +609,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } #if __cplusplus >= 201103L /** diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index ebac767..f150471 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -186,7 +186,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> multiset(_InputIterator __first, _InputIterator __last) : _M_t() - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } /** * @brief Builds a %multiset from a range. @@ -204,7 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } /** * @brief %Multiset copy constructor. @@ -240,7 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) - { _M_t._M_insert_equal(__l.begin(), __l.end()); } + { _M_t._M_insert_range_equal(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit @@ -260,14 +260,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Allocator-extended initialier-list constructor. multiset(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Key_alloc_type(__a)) - { _M_t._M_insert_equal(__l.begin(), __l.end()); } + { _M_t._M_insert_range_equal(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> multiset(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Key_alloc_type(__a)) - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } /** * The dtor only erases the elements, and note that if the elements @@ -549,7 +549,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) - { _M_t._M_insert_equal(__first, __last); } + { _M_t._M_insert_range_equal(__first, __last); } #if __cplusplus >= 201103L /** diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index ee959d5..a8d10d5 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> set(_InputIterator __first, _InputIterator __last) : _M_t() - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } /** * @brief Builds a %set from a range. @@ -209,7 +209,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } /** * @brief %Set copy constructor. @@ -244,7 +244,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) - { _M_t._M_insert_unique(__l.begin(), __l.end()); } + { _M_t._M_insert_range_unique(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit @@ -264,14 +264,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Allocator-extended initialier-list constructor. set(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Key_alloc_type(__a)) - { _M_t._M_insert_unique(__l.begin(), __l.end()); } + { _M_t._M_insert_range_unique(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> set(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Key_alloc_type(__a)) - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } /** * The dtor only erases the elements, and note that if the elements @@ -564,7 +564,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) - { _M_t._M_insert_unique(__first, __last); } + { _M_t._M_insert_range_unique(__first, __last); } #if __cplusplus >= 201103L /** diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 09e8d75..70d7483 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1104,6 +1104,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Args> iterator _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args); + + template<typename _Iter> + using __same_value_type + = is_same<value_type, typename iterator_traits<_Iter>::value_type>; + + template<typename _InputIterator> + __enable_if_t<__same_value_type<_InputIterator>::value> + _M_insert_range_unique(_InputIterator __first, _InputIterator __last) + { + _Alloc_node __an(*this); + for (; __first != __last; ++__first) + _M_insert_unique_(end(), *__first, __an); + } + + template<typename _InputIterator> + __enable_if_t<!__same_value_type<_InputIterator>::value> + _M_insert_range_unique(_InputIterator __first, _InputIterator __last) + { + for (; __first != __last; ++__first) + _M_emplace_unique(*__first); + } + + template<typename _InputIterator> + __enable_if_t<__same_value_type<_InputIterator>::value> + _M_insert_range_equal(_InputIterator __first, _InputIterator __last) + { + _Alloc_node __an(*this); + for (; __first != __last; ++__first) + _M_insert_equal_(end(), *__first, __an); + } + + template<typename _InputIterator> + __enable_if_t<!__same_value_type<_InputIterator>::value> + _M_insert_range_equal(_InputIterator __first, _InputIterator __last) + { + _Alloc_node __an(*this); + for (; __first != __last; ++__first) + _M_emplace_equal(*__first); + } #else pair<iterator, bool> _M_insert_unique(const value_type& __x); @@ -1133,15 +1172,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Alloc_node __an(*this); return _M_insert_equal_(__pos, __x, __an); } -#endif template<typename _InputIterator> void - _M_insert_unique(_InputIterator __first, _InputIterator __last); + _M_insert_range_unique(_InputIterator __first, _InputIterator __last) + { + _Alloc_node __an(*this); + for (; __first != __last; ++__first) + _M_insert_unique_(end(), *__first, __an); + } template<typename _InputIterator> void - _M_insert_equal(_InputIterator __first, _InputIterator __last); + _M_insert_range_equal(_InputIterator __first, _InputIterator __last) + { + _Alloc_node __an(*this); + for (; __first != __last; ++__first) + _M_insert_equal_(end(), *__first, __an); + } +#endif private: void @@ -2471,29 +2520,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif - template<typename _Key, typename _Val, typename _KoV, - typename _Cmp, typename _Alloc> - template<class _II> - void - _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: - _M_insert_unique(_II __first, _II __last) - { - _Alloc_node __an(*this); - for (; __first != __last; ++__first) - _M_insert_unique_(end(), *__first, __an); - } - - template<typename _Key, typename _Val, typename _KoV, - typename _Cmp, typename _Alloc> - template<class _II> - void - _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: - _M_insert_equal(_II __first, _II __last) - { - _Alloc_node __an(*this); - for (; __first != __last; ++__first) - _M_insert_equal_(end(), *__first, __an); - } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> diff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/87194.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/87194.cc new file mode 100644 index 0000000..4daba40 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/87194.cc @@ -0,0 +1,46 @@ +// Copyright (C) 2018 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/>. + +// { dg-do run { target c++11 } } + +#include <map> +#include <iterator> +#include <testsuite_hooks.h> + +struct S +{ + operator std::pair<const int, int>() && + { int i = val; val = 0; return {i, 0}; } + + int val; +}; + +void +test01() +{ + S a[3] = { {1}, {2}, {3} }; + std::map<int, int> s; + s.insert(std::make_move_iterator(a), std::make_move_iterator(a+3)); + VERIFY( s.size() == 3 ); + VERIFY( s.find(0) == s.end() ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/87194.cc b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/87194.cc new file mode 100644 index 0000000..8a47101 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/87194.cc @@ -0,0 +1,46 @@ +// Copyright (C) 2018 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/>. + +// { dg-do run { target c++11 } } + +#include <map> +#include <iterator> +#include <testsuite_hooks.h> + +struct S +{ + operator std::pair<const int, int>() && + { int i = val; val = 0; return {i, 0}; } + + int val; +}; + +void +test01() +{ + S a[3] = { {1}, {2}, {3} }; + std::multimap<int, int> s; + s.insert(std::make_move_iterator(a), std::make_move_iterator(a+3)); + VERIFY( s.size() == 3 ); + VERIFY( s.find(0) == s.end() ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/87194.cc b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/87194.cc new file mode 100644 index 0000000..c2a21d3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/87194.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2018 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/>. + +// { dg-do run { target c++11 } } + +#include <set> +#include <iterator> +#include <testsuite_hooks.h> + +struct S { + S(int v) : val(v) {} + operator int() && { int i = val; val = 0; return i; } + int val; +}; + +void +test01() +{ + S a[3] = { {1}, {2}, {3} }; + std::multiset<int> s; + s.insert(std::make_move_iterator(a), std::make_move_iterator(a+3)); + VERIFY( s.size() == 3 ); + VERIFY( s.find(0) == s.end() ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/insert/87194.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/insert/87194.cc new file mode 100644 index 0000000..14bf54e --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/insert/87194.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2018 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/>. + +// { dg-do run { target c++11 } } + +#include <set> +#include <iterator> +#include <testsuite_hooks.h> + +struct S { + S(int v) : val(v) {} + operator int() && { int i = val; val = 0; return i; } + int val; +}; + +void +test01() +{ + S a[3] = { {1}, {2}, {3} }; + std::set<int> s; + s.insert(std::make_move_iterator(a), std::make_move_iterator(a+3)); + VERIFY( s.size() == 3 ); + VERIFY( s.find(0) == s.end() ); +} + +int +main() +{ + test01(); +} |