This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] plus<void>


Hello,

this was only minimally tested since trunk is broken at the moment. There don't seem to be specific tests for the existing functors, so a couple tests for the new specializations seem good enough.

2013-09-25  Marc Glisse  <marc.glisse@inria.fr>

	* include/bits/stl_function.h: Include <bits/move.h> for std::forward.
	(bit_not): New class.
	(plus<void>, minus<void> ,multiplies<void>, divides<void>,
	modulus<void>, negate<void>, equal_to<void>, not_equal_to<void>,
	greater<void>, less<void>, greater_equal<void>, less_equal<void>,
	logical_and<void>, logical_or<void>, logical_not<void>, bit_and<void>,
	bit_or<void>, bit_xor<void>, bit_not<void>): New specializations.
	* testsuite/20_util/headers/functional/generic_function_objects.cc:
	New file.

--
Marc Glisse
Index: include/bits/stl_function.h
===================================================================
--- include/bits/stl_function.h	(revision 202872)
+++ include/bits/stl_function.h	(working copy)
@@ -49,20 +49,22 @@
  */
 
 /** @file bits/stl_function.h
  *  This is an internal header file, included by other library headers.
  *  Do not attempt to use it directly. @headername{functional}
  */
 
 #ifndef _STL_FUNCTION_H
 #define _STL_FUNCTION_H 1
 
+#include <bits/move.h> // for std::forward
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // 20.3.1 base classes
   /** @defgroup functors Function Objects
    * @ingroup utilities
    *
    *  Function objects, or @e functors, are objects with an @c operator()
    *  defined and accessible.  They can be passed as arguments to algorithm
@@ -129,201 +131,514 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @ingroup functors
    *
    *  Because basic math often needs to be done during an algorithm,
    *  the library provides functors for those operations.  See the
    *  documentation for @link functors the base classes@endlink
    *  for examples of their use.
    *
    *  @{
    */
   /// One of the @link arithmetic_functors math functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct plus : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x + __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct plus<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) + std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) + std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) + std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link arithmetic_functors math functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct minus : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x - __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct minus<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) - std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) - std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) - std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link arithmetic_functors math functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct multiplies : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x * __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct multiplies<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) * std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) * std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) * std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link arithmetic_functors math functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct divides : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x / __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct divides<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) / std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) / std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) / std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link arithmetic_functors math functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct modulus : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x % __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct modulus<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) % std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) % std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) % std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link arithmetic_functors math functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct negate : public unary_function<_Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x) const
       { return -__x; }
     };
+
+#if __cplusplus >= 201103L
+  template<>
+    struct negate<void>
+    {
+      template <class _Tp>
+      constexpr auto
+      operator()(_Tp&& __x) const
+      noexcept(noexcept(-std::forward<_Tp>(__x)))
+      -> decltype(-std::forward<_Tp>(__x))
+      {
+	return -std::forward<_Tp>(__x);
+      }
+      typedef void is_transparent;
+  };
+#endif
   /** @}  */
 
   // 20.3.3 comparisons
   /** @defgroup comparison_functors Comparison Classes
    * @ingroup functors
    *
    *  The library provides six wrapper functors for all the basic comparisons
    *  in C++, like @c <.
    *
    *  @{
    */
   /// One of the @link comparison_functors comparison functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct equal_to : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x == __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct equal_to<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) == std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) == std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) == std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link comparison_functors comparison functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct not_equal_to : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x != __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct not_equal_to<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) != std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) != std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) != std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link comparison_functors comparison functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct greater : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x > __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct greater<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) > std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) > std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) > std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link comparison_functors comparison functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct less : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x < __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct less<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) < std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) < std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) < std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link comparison_functors comparison functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct greater_equal : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x >= __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct greater_equal<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) >= std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) >= std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) >= std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link comparison_functors comparison functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct less_equal : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x <= __y; }
     };
+
+#if __cplusplus >= 201103L
+  template<>
+    struct less_equal<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) <= std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) <= std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) <= std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /** @}  */
 
   // 20.3.4 logical operations
   /** @defgroup logical_functors Boolean Operations Classes
    * @ingroup functors
    *
    *  Here are wrapper functors for Boolean operations: @c &&, @c ||,
    *  and @c !.
    *
    *  @{
    */
   /// One of the @link logical_functors Boolean operations functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct logical_and : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x && __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct logical_and<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) && std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) && std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) && std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link logical_functors Boolean operations functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct logical_or : public binary_function<_Tp, _Tp, bool>
     {
       bool
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x || __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct logical_or<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) || std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) || std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) || std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   /// One of the @link logical_functors Boolean operations functors@endlink.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct logical_not : public unary_function<_Tp, bool>
     {
       bool
       operator()(const _Tp& __x) const
       { return !__x; }
     };
+
+#if __cplusplus >= 201103L
+  template<>
+    struct logical_not<void>
+    {
+      template <class _Tp>
+      constexpr auto
+      operator()(_Tp&& __x) const
+      noexcept(noexcept(!std::forward<_Tp>(__x)))
+      -> decltype(!std::forward<_Tp>(__x))
+      {
+	return !std::forward<_Tp>(__x);
+      }
+      typedef void is_transparent;
+  };
+#endif
   /** @}  */
 
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // DR 660. Missing Bitwise Operations.
-  template<typename _Tp>
+  template<typename _Tp = void>
     struct bit_and : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x & __y; }
     };
 
-  template<typename _Tp>
+#if __cplusplus >= 201103L
+  template<>
+    struct bit_and<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) & std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) & std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) & std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
+  template<typename _Tp = void>
     struct bit_or : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x | __y; }
     };
 
-  template<typename _Tp>
+#if __cplusplus >= 201103L
+  template<>
+    struct bit_or<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) | std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) | std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) | std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
+  template<typename _Tp = void>
     struct bit_xor : public binary_function<_Tp, _Tp, _Tp>
     {
       _Tp
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x ^ __y; }
     };
 
+#if __cplusplus >= 201103L
+  template<>
+    struct bit_xor<void>
+    {
+      template <class _Tp, class _Up>
+      constexpr auto
+      operator()(_Tp&& __x, _Up&& __y) const
+      noexcept(noexcept(std::forward<_Tp>(__x) ^ std::forward<_Up>(__y)))
+      -> decltype(std::forward<_Tp>(__x) ^ std::forward<_Up>(__y))
+      {
+	return std::forward<_Tp>(__x) ^ std::forward<_Up>(__y);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
+  template<typename _Tp = void>
+    struct bit_not : public unary_function<_Tp, _Tp>
+    {
+      _Tp
+      operator()(const _Tp& __x) const
+      { return ~__x; }
+    };
+
+#if __cplusplus >= 201103L
+  template<>
+    struct bit_not<void>
+    {
+      template <class _Tp>
+      constexpr auto
+      operator()(_Tp&& __x) const
+      noexcept(noexcept(~std::forward<_Tp>(__x)))
+      -> decltype(~std::forward<_Tp>(__x))
+      {
+	return ~std::forward<_Tp>(__x);
+      }
+      typedef void is_transparent;
+  };
+#endif
+
   // 20.3.5 negators
   /** @defgroup negators Negators
    * @ingroup functors
    *
    *  The functions @c not1 and @c not2 each take a predicate functor
    *  and return an instance of @c unary_negate or
    *  @c binary_negate, respectively.  These classes are functors whose
    *  @c operator() performs the stored predicate function and then returns
    *  the negation of the result.
    *
Index: testsuite/20_util/headers/functional/generic_function_objects.cc
===================================================================
--- testsuite/20_util/headers/functional/generic_function_objects.cc	(revision 0)
+++ testsuite/20_util/headers/functional/generic_function_objects.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 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 <functional>
+#include <type_traits>
+
+struct A{};
+extern A a;
+struct B{};
+struct C{};
+C operator<(A&,B&&);
+struct D{};
+struct E{};
+E& operator~(D);
+static_assert (std::is_same<
+    decltype(std::less<void>{} (a, B{})),
+    C >::value, "Meh?");
+static_assert (std::is_same<
+    decltype(std::bit_not<void>{} (D{})),
+    E& >::value, "Bah...");

Property changes on: testsuite/20_util/headers/functional/generic_function_objects.cc
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision URL
\ No newline at end of property

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]