From: Jonathan Wakely Date: Mon, 3 Sep 2018 14:25:25 +0000 (+0100) Subject: PR libstdc++/87194 fix range insertion into maps and sets X-Git-Tag: upstream/12.2.0~29442 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=83a840a91fb3281f8980eaacdb7b5377778da3bb;p=platform%2Fupstream%2Fgcc.git 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, const Compare&, const Alloc&)) (map::map(initializer_list, 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, const C&, const A&)) (multimap::multimap(initializer_list, 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, const C&, const A&)) (multiset::multiset(initializer_list, 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, const Compare&, const Alloc&)) (set::set(initializer_list, 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 --- 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 + PR libstdc++/87194 + * include/bits/stl_map.h + (map::map(initializer_list, const Compare&, const Alloc&)) + (map::map(initializer_list, 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, const C&, const A&)) + (multimap::multimap(initializer_list, 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, const C&, const A&)) + (multiset::multiset(initializer_list, 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, const Compare&, const Alloc&)) + (set::set(initializer_list, 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 __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 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 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 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 __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 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 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 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 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 __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 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 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 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 __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 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 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 iterator _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args); + + template + using __same_value_type + = is_same::value_type>; + + template + __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 + __enable_if_t::value> + _M_insert_range_unique(_InputIterator __first, _InputIterator __last) + { + for (; __first != __last; ++__first) + _M_emplace_unique(*__first); + } + + template + __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 + __enable_if_t::value> + _M_insert_range_equal(_InputIterator __first, _InputIterator __last) + { + _Alloc_node __an(*this); + for (; __first != __last; ++__first) + _M_emplace_equal(*__first); + } #else pair _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 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 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 - template - 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 - template - 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 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +struct S +{ + operator std::pair() && + { int i = val; val = 0; return {i, 0}; } + + int val; +}; + +void +test01() +{ + S a[3] = { {1}, {2}, {3} }; + std::map 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +struct S +{ + operator std::pair() && + { int i = val; val = 0; return {i, 0}; } + + int val; +}; + +void +test01() +{ + S a[3] = { {1}, {2}, {3} }; + std::multimap 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +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 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +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 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(); +}