PR78991 make __gnu_cxx::__ops constructors explicit
authorJonathan Wakely <jwakely@redhat.com>
Fri, 6 Jan 2017 12:33:58 +0000 (12:33 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 6 Jan 2017 12:33:58 +0000 (12:33 +0000)
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
libstdc++-v3/include/bits/predefined_ops.h
libstdc++-v3/testsuite/25_algorithms/sort/78991.cc [new file with mode: 0644]

index 7b2199d52c7f849b71b558cb5476bbe70c8998e2..bf4f415c15db8194a3d1e0c813cb0b60c926342d 100644 (file)
@@ -1,3 +1,14 @@
+2017-01-06  Jonathan Wakely  <jwakely@redhat.com>
+
+       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  <jwakely@redhat.com>
 
        * include/bits/std_function.h (function::_Signature_type): Remove.
index 92feef39fd26db7ec860b86bf00b31c9f4788c67..2742984b6470946755e080cc8b7ac5f2e02af9f4 100644 (file)
@@ -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<typename _Iterator1, typename _Iterator2>
@@ -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<typename _Compare>
     struct _Iter_comp_val
     {
       _Compare _M_comp;
 
+      explicit
       _Iter_comp_val(_Compare __comp)
-       : _M_comp(__comp)
+       : _M_comp(_GLIBCXX_MOVE(__comp))
       { }
 
       template<typename _Iterator, typename _Value>
@@ -147,20 +150,21 @@ namespace __ops
   template<typename _Compare>
    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<typename _Compare>
     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<typename _Compare>
     struct _Val_comp_iter
     {
       _Compare _M_comp;
 
+      explicit
       _Val_comp_iter(_Compare __comp)
-       : _M_comp(__comp)
+       : _M_comp(_GLIBCXX_MOVE(__comp))
       { }
 
       template<typename _Value, typename _Iterator>
@@ -172,18 +176,19 @@ namespace __ops
   template<typename _Compare>
     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<typename _Compare>
     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<typename _Value>
     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<typename _Iterator>
@@ -237,7 +244,7 @@ namespace __ops
   template<typename _Predicate>
     inline _Iter_pred<_Predicate>
     __pred_iter(_Predicate __pred)
-    { return _Iter_pred<_Predicate>(__pred); }
+    { return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); }
 
   template<typename _Compare, typename _Value>
     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<typename _Iterator>
@@ -258,7 +265,9 @@ namespace __ops
   template<typename _Compare, typename _Value>
     _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<typename _Compare, typename _Iterator1>
     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<typename _Iterator2>
@@ -279,15 +288,19 @@ namespace __ops
   template<typename _Compare, typename _Iterator>
     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<typename _Predicate>
     struct _Iter_negate
     {
       _Predicate _M_pred;
 
+      explicit
       _Iter_negate(_Predicate __pred)
-       : _M_pred(__pred)
+       : _M_pred(_GLIBCXX_MOVE(__pred))
       { }
 
       template<typename _Iterator>
@@ -299,7 +312,7 @@ namespace __ops
   template<typename _Predicate>
     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 (file)
index 0000000..472763d
--- /dev/null
@@ -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
+// <http://www.gnu.org/licenses/>.
+
+// { 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 <algorithm>
+
+struct function
+{
+  function() = default;
+
+  template<typename F, typename = std::result_of_t<F&(int, int)>>
+    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{});
+}