From 6807f0862833c893bdcdc6838e9303761d93929a Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 6 Jan 2017 12:33:58 +0000 Subject: [PATCH] PR78991 make __gnu_cxx::__ops constructors explicit PR libstdc++/78991 * include/bits/predefined_ops.h (_Iter_comp_iter, _Iter_comp_val) (_Val_comp_iter, _Iter_equals_val, _Iter_pred, _Iter_comp_to_val) (_Iter_comp_to_iter, _Iter_negate): Make constructors explicit and move function objects. (__iter_comp_iter, __iter_comp_val, __val_comp_iter, __pred_iter) (__iter_comp_val, __iter_comp_iter, __negate): Move function objects. * testsuite/25_algorithms/sort/78991.cc: New test. From-SVN: r244150 --- libstdc++-v3/ChangeLog | 11 ++++ libstdc++-v3/include/bits/predefined_ops.h | 55 ++++++++++++------- .../testsuite/25_algorithms/sort/78991.cc | 40 ++++++++++++++ 3 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 libstdc++-v3/testsuite/25_algorithms/sort/78991.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7b2199d52c7..bf4f415c15d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2017-01-06 Jonathan Wakely + + PR libstdc++/78991 + * include/bits/predefined_ops.h (_Iter_comp_iter, _Iter_comp_val) + (_Val_comp_iter, _Iter_equals_val, _Iter_pred, _Iter_comp_to_val) + (_Iter_comp_to_iter, _Iter_negate): Make constructors explicit and + move function objects. + (__iter_comp_iter, __iter_comp_val, __val_comp_iter, __pred_iter) + (__iter_comp_val, __iter_comp_iter, __negate): Move function objects. + * testsuite/25_algorithms/sort/78991.cc: New test. + 2017-01-05 Jonathan Wakely * include/bits/std_function.h (function::_Signature_type): Remove. diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h index 92feef39fd2..2742984b647 100644 --- a/libstdc++-v3/include/bits/predefined_ops.h +++ b/libstdc++-v3/include/bits/predefined_ops.h @@ -42,6 +42,7 @@ namespace __ops operator()(_Iterator1 __it1, _Iterator2 __it2) const { return *__it1 < *__it2; } }; + _GLIBCXX14_CONSTEXPR inline _Iter_less_iter __iter_less_iter() @@ -53,7 +54,7 @@ namespace __ops bool operator()(_Iterator __it, _Value& __val) const { return *__it < __val; } - }; + }; inline _Iter_less_val __iter_less_val() @@ -69,7 +70,7 @@ namespace __ops bool operator()(_Value& __val, _Iterator __it) const { return __val < *__it; } - }; + }; inline _Val_less_iter __val_less_iter() @@ -85,7 +86,7 @@ namespace __ops bool operator()(_Iterator1 __it1, _Iterator2 __it2) const { return *__it1 == *__it2; } - }; + }; inline _Iter_equal_to_iter __iter_equal_to_iter() @@ -97,7 +98,7 @@ namespace __ops bool operator()(_Iterator __it, _Value& __val) const { return *__it == __val; } - }; + }; inline _Iter_equal_to_val __iter_equal_to_val() @@ -111,9 +112,10 @@ namespace __ops struct _Iter_comp_iter { _Compare _M_comp; - _GLIBCXX14_CONSTEXPR + + explicit _GLIBCXX14_CONSTEXPR _Iter_comp_iter(_Compare __comp) - : _M_comp(__comp) + : _M_comp(_GLIBCXX_MOVE(__comp)) { } template @@ -127,15 +129,16 @@ namespace __ops _GLIBCXX14_CONSTEXPR inline _Iter_comp_iter<_Compare> __iter_comp_iter(_Compare __comp) - { return _Iter_comp_iter<_Compare>(__comp); } + { return _Iter_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); } template struct _Iter_comp_val { _Compare _M_comp; + explicit _Iter_comp_val(_Compare __comp) - : _M_comp(__comp) + : _M_comp(_GLIBCXX_MOVE(__comp)) { } template @@ -147,20 +150,21 @@ namespace __ops template inline _Iter_comp_val<_Compare> __iter_comp_val(_Compare __comp) - { return _Iter_comp_val<_Compare>(__comp); } + { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); } template inline _Iter_comp_val<_Compare> __iter_comp_val(_Iter_comp_iter<_Compare> __comp) - { return _Iter_comp_val<_Compare>(__comp._M_comp); } + { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp._M_comp)); } template struct _Val_comp_iter { _Compare _M_comp; + explicit _Val_comp_iter(_Compare __comp) - : _M_comp(__comp) + : _M_comp(_GLIBCXX_MOVE(__comp)) { } template @@ -172,18 +176,19 @@ namespace __ops template inline _Val_comp_iter<_Compare> __val_comp_iter(_Compare __comp) - { return _Val_comp_iter<_Compare>(__comp); } + { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); } template inline _Val_comp_iter<_Compare> __val_comp_iter(_Iter_comp_iter<_Compare> __comp) - { return _Val_comp_iter<_Compare>(__comp._M_comp); } + { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp._M_comp)); } template struct _Iter_equals_val { _Value& _M_value; + explicit _Iter_equals_val(_Value& __value) : _M_value(__value) { } @@ -204,6 +209,7 @@ namespace __ops { typename std::iterator_traits<_Iterator1>::reference _M_ref; + explicit _Iter_equals_iter(_Iterator1 __it1) : _M_ref(*__it1) { } @@ -224,8 +230,9 @@ namespace __ops { _Predicate _M_pred; + explicit _Iter_pred(_Predicate __pred) - : _M_pred(__pred) + : _M_pred(_GLIBCXX_MOVE(__pred)) { } template @@ -237,7 +244,7 @@ namespace __ops template inline _Iter_pred<_Predicate> __pred_iter(_Predicate __pred) - { return _Iter_pred<_Predicate>(__pred); } + { return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); } template struct _Iter_comp_to_val @@ -246,7 +253,7 @@ namespace __ops _Value& _M_value; _Iter_comp_to_val(_Compare __comp, _Value& __value) - : _M_comp(__comp), _M_value(__value) + : _M_comp(_GLIBCXX_MOVE(__comp)), _M_value(__value) { } template @@ -258,7 +265,9 @@ namespace __ops template _Iter_comp_to_val<_Compare, _Value> __iter_comp_val(_Compare __comp, _Value &__val) - { return _Iter_comp_to_val<_Compare, _Value>(__comp, __val); } + { + return _Iter_comp_to_val<_Compare, _Value>(_GLIBCXX_MOVE(__comp), __val); + } template struct _Iter_comp_to_iter @@ -267,7 +276,7 @@ namespace __ops typename std::iterator_traits<_Iterator1>::reference _M_ref; _Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1) - : _M_comp(__comp), _M_ref(*__it1) + : _M_comp(_GLIBCXX_MOVE(__comp)), _M_ref(*__it1) { } template @@ -279,15 +288,19 @@ namespace __ops template inline _Iter_comp_to_iter<_Compare, _Iterator> __iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it) - { return _Iter_comp_to_iter<_Compare, _Iterator>(__comp._M_comp, __it); } + { + return _Iter_comp_to_iter<_Compare, _Iterator>( + _GLIBCXX_MOVE(__comp._M_comp), __it); + } template struct _Iter_negate { _Predicate _M_pred; + explicit _Iter_negate(_Predicate __pred) - : _M_pred(__pred) + : _M_pred(_GLIBCXX_MOVE(__pred)) { } template @@ -299,7 +312,7 @@ namespace __ops template inline _Iter_negate<_Predicate> __negate(_Iter_pred<_Predicate> __pred) - { return _Iter_negate<_Predicate>(__pred._M_pred); } + { return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); } } // namespace __ops } // namespace __gnu_cxx diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/78991.cc b/libstdc++-v3/testsuite/25_algorithms/sort/78991.cc new file mode 100644 index 00000000000..472763deb54 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/sort/78991.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 compile { target c++14 } } + +// PR 78991 +// This failed to compile with Clang because the result_of expression causes +// instantiation of _Iter_comp_iter::operator() outside the immediate context. + +#include + +struct function +{ + function() = default; + + template> + function(F) { } + + bool operator()(int x, int y) const { return x < y; } +}; + +int main() +{ + int a[2]{ 2, 1 }; + std::sort(a, a+2, function{}); +} -- 2.30.2