commit 64cfa93cbe00a5340bc454f9b70adefd9fd69d35
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Tue May 21 08:55:24 2013 +0100

    	* include/bits/stl_function.h: Implement N3421.
    	* testsuite/20_util/function_objects/comparisons_void.cc: New.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d46fbcf..6501121 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
 2013-05-21  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
+	* include/bits/stl_function.h: Implement N3421.
+	* testsuite/20_util/function_objects/comparisons_void.cc: New.
+
+2013-05-21  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
 	PR libstdc++/57336
 	* include/std/functional (__invoke): Do not form function types with
 	abstract return type.
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index 23529df..f1bb10c 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -56,6 +56,10 @@
 #ifndef _STL_FUNCTION_H
 #define _STL_FUNCTION_H 1
 
+#if __cplusplus > 201103L
+#include <bits/move.h>
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -135,6 +139,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *
    *  @{
    */
+
+#if __cplusplus > 201103L
+  struct __is_transparent;  // undefined
+
+  template<typename _Tp = void>
+    struct plus;
+
+  template<typename _Tp = void>
+    struct minus;
+
+  template<typename _Tp = void>
+    struct multiplies;
+
+  template<typename _Tp = void>
+    struct divides;
+
+  template<typename _Tp = void>
+    struct modulus;
+
+  template<typename _Tp = void>
+    struct negate;
+#endif
+
   /// One of the @link arithmetic_functors math functors@endlink.
   template<typename _Tp>
     struct plus : public binary_function<_Tp, _Tp, _Tp>
@@ -188,6 +215,84 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(const _Tp& __x) const
       { return -__x; }
     };
+
+#if __cplusplus > 201103L
+  template<>
+    struct plus<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) + std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) + std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link arithmetic_functors math functors@endlink.
+  template<>
+    struct minus<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) - std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) - std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link arithmetic_functors math functors@endlink.
+  template<>
+    struct multiplies<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) * std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) * std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link arithmetic_functors math functors@endlink.
+  template<>
+    struct divides<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) / std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) / std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link arithmetic_functors math functors@endlink.
+  template<>
+    struct modulus<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) % std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) % std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link arithmetic_functors math functors@endlink.
+  template<>
+    struct negate<void>
+    {
+      template <typename _Tp>
+	auto
+	operator()(_Tp&& __t) const -> decltype(-std::forward<_Tp>(__t))
+	{ return -std::forward<_Tp>(__t); }
+
+      typedef __is_transparent is_transparent;
+    };
+#endif
   /** @}  */
 
   // 20.3.3 comparisons
@@ -199,6 +304,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *
    *  @{
    */
+#if __cplusplus > 201103L
+  template<typename _Tp = void>
+    struct equal_to;
+
+  template<typename _Tp = void>
+    struct not_equal_to;
+
+  template<typename _Tp = void>
+    struct greater;
+
+  template<typename _Tp = void>
+    struct less;
+
+  template<typename _Tp = void>
+    struct greater_equal;
+
+  template<typename _Tp = void>
+    struct less_equal;
+#endif
+
   /// One of the @link comparison_functors comparison functors@endlink.
   template<typename _Tp>
     struct equal_to : public binary_function<_Tp, _Tp, bool>
@@ -252,6 +377,86 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(const _Tp& __x, const _Tp& __y) const
       { return __x <= __y; }
     };
+
+#if __cplusplus > 201103L
+  /// One of the @link comparison_functors comparison functors@endlink.
+  template<>
+    struct equal_to<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) == std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link comparison_functors comparison functors@endlink.
+  template<>
+    struct not_equal_to<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) != std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) != std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link comparison_functors comparison functors@endlink.
+  template<>
+    struct greater<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) > std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) > std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link comparison_functors comparison functors@endlink.
+  template<>
+    struct less<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) < std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link comparison_functors comparison functors@endlink.
+  template<>
+    struct greater_equal<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) >= std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) >= std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link comparison_functors comparison functors@endlink.
+  template<>
+    struct less_equal<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) <= std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) <= std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+#endif
   /** @}  */
 
   // 20.3.4 logical operations
@@ -263,6 +468,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *
    *  @{
    */
+#if __cplusplus > 201103L
+  template<typename _Tp = void>
+    struct logical_and;
+
+  template<typename _Tp = void>
+    struct logical_or;
+
+  template<typename _Tp = void>
+    struct logical_not;
+#endif
+
   /// One of the @link logical_functors Boolean operations functors@endlink.
   template<typename _Tp>
     struct logical_and : public binary_function<_Tp, _Tp, bool>
@@ -289,8 +505,62 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator()(const _Tp& __x) const
       { return !__x; }
     };
+
+#if __cplusplus > 201103L
+  /// One of the @link logical_functors Boolean operations functors@endlink.
+  template<>
+    struct logical_and<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) && std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) && std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link logical_functors Boolean operations functors@endlink.
+  template<>
+    struct logical_or<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) || std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) || std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  /// One of the @link logical_functors Boolean operations functors@endlink.
+  template<>
+    struct logical_not<void>
+    {
+      template <typename _Tp>
+	auto
+	operator()(_Tp&& __t) const -> decltype(!std::forward<_Tp>(__t))
+	{ return !std::forward<_Tp>(__t); }
+
+      typedef __is_transparent is_transparent;
+    };
+#endif
   /** @}  */
 
+#if __cplusplus > 201103L
+  template<typename _Tp = void>
+    struct bit_and;
+
+  template<typename _Tp = void>
+    struct bit_or;
+
+  template<typename _Tp = void>
+    struct bit_xor;
+
+  template<typename _Tp = void>
+    struct bit_not;
+#endif
+
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // DR 660. Missing Bitwise Operations.
   template<typename _Tp>
@@ -317,6 +587,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return __x ^ __y; }
     };
 
+  template<typename _Tp>
+    struct bit_not : public unary_function<_Tp, _Tp>
+    {
+      _Tp
+      operator()(const _Tp& __x) const
+      { return ~__x; }
+    };
+
+#if __cplusplus > 201103L
+  template <>
+    struct bit_and<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) & std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) & std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  template <>
+    struct bit_or<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) | std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) | std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  template <>
+    struct bit_xor<void>
+    {
+      template <typename _Tp, typename _Up>
+	auto
+	operator()(_Tp&& __t, _Up&& __u) const
+	-> decltype(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u))
+	{ return std::forward<_Tp>(__t) ^ std::forward<_Up>(__u); }
+
+      typedef __is_transparent is_transparent;
+    };
+
+  template <>
+    struct bit_not<void>
+    {
+      template <typename _Tp>
+	auto
+	operator()(_Tp&& __t) const -> decltype(~std::forward<_Tp>(__t))
+	{ return ~std::forward<_Tp>(__t); }
+
+      typedef __is_transparent is_transparent;
+    };
+#endif
+
   // 20.3.5 negators
   /** @defgroup negators Negators
    * @ingroup functors
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/comparisons_void.cc b/libstdc++-v3/testsuite/20_util/function_objects/comparisons_void.cc
new file mode 100644
index 0000000..e273dbc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function_objects/comparisons_void.cc
@@ -0,0 +1,88 @@
+// { dg-options " -std=gnu++1y " }
+// { 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/>.
+
+// 20.3.3 Comparisons
+
+#include <functional>
+
+struct R { };
+
+struct L
+{
+  L operator+(const R&) const { return *this; }
+  L operator-(const R&) const { return *this; }
+  L operator*(const R&) const { return *this; }
+  L operator/(const R&) const { return *this; }
+  L operator%(const R&) const { return *this; }
+  L operator-() const { return *this; }
+
+  bool operator==(const R&) const { return true; }
+  bool operator!=(const R&) const { return false; }
+  bool operator<(const R&) const { return false; }
+  bool operator<=(const R&) const { return true; }
+  bool operator>(const R&) const { return false; }
+  bool operator>=(const R&) const { return true; }
+};
+
+L l;
+R r;
+
+// test unary function objects
+template<typename F>
+bool
+test1(F f)
+{
+  f(l);
+  typedef typename F::is_transparent check;
+  return sizeof(check);
+}
+
+// test binary function objects
+template<typename F>
+bool
+test2(F f)
+{
+  f(l, r);
+  typedef typename F::is_transparent check;
+  return sizeof(check);
+}
+
+auto plus       = test2( std::plus<>() );
+auto minus      = test2( std::minus<>() );
+auto multiplies = test2( std::multiplies<>() );
+auto divides    = test2( std::divides<>() );
+auto modulus    = test2( std::modulus<>() );
+auto negate     = test1( std::negate<>() );
+
+auto equal_to       = test2( std::equal_to<>() );
+auto not_equal_to   = test2( std::not_equal_to<>() );
+auto greater        = test2( std::greater<>() );
+auto less           = test2( std::less<>() );
+auto greater_equal  = test2( std::greater_equal<>() );
+auto less_equal     = test2( std::less_equal<>() );
+
+auto logical_and    = test2( std::logical_and<>() );
+auto logical_or     = test2( std::logical_or<>() );
+auto logical_not    = test1( std::logical_not<>() );
+
+auto bit_and        = test2( std::bit_and<>() );
+auto bit_or         = test2( std::bit_or<>() );
+auto bit_xor        = test2( std::bit_xor<>() );
+auto bit_not        = test1( std::bit_not<>() );
