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.gli...@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