This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] plus<void>
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: libstdc++ at gcc dot gnu dot org
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 25 Sep 2013 00:37:12 +0200 (CEST)
- Subject: [v3] plus<void>
- Authentication-results: sourceware.org; auth=none
- Reply-to: libstdc++ at gcc dot gnu dot org
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