From patchwork Tue Sep 24 22:37:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 277640 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 438432C00CF for ; Wed, 25 Sep 2013 08:37:37 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:reply-to:to:cc:subject:message-id:mime-version :content-type; q=dns; s=default; b=OGEB0YvMTM90ocHhuwAlAvwZtTwO8 4UwlqXZHMKwvsntUbRijhupGuJ1tTsv/K8BSrSqROv2s9rd25sfR6wrMzDSgsGri dzsi/KHwYLXCRQ+qZrTaQhl3I6EDru5r7YWv0Nw0m2VKriHYgLd/g9gcP3jnmJaz 7dv1jTsv+p0gCk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:reply-to:to:cc:subject:message-id:mime-version :content-type; s=default; bh=HQMOmHKWEjII11NOuENC6ijQN4s=; b=iKO sn92rhGmANpHJ/Fbkapy9qAOx87w3rljlcHRzVV6xiAcODQHTFMa1l/xA3ostzcU S3tZGOyOERix+dqpCigDiQZ40Q5TD4maXMIKGc9txU8gH8zJN5knESiG5PjHIPHg 76c+D+tEiPOgr5S7u21QS7lFtF8UT6MbPXQ3hIZc= Received: (qmail 1819 invoked by alias); 24 Sep 2013 22:37:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 1792 invoked by uid 89); 24 Sep 2013 22:37:19 -0000 Received: from mail2-relais-roc.national.inria.fr (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 24 Sep 2013 22:37:19 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_00, RDNS_NONE autolearn=no version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail2-relais-roc.national.inria.fr Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 25 Sep 2013 00:37:13 +0200 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1VObEG-0006vR-QF; Wed, 25 Sep 2013 00:37:12 +0200 Date: Wed, 25 Sep 2013 00:37:12 +0200 (CEST) From: Marc Glisse Reply-To: libstdc++@gcc.gnu.org To: libstdc++@gcc.gnu.org cc: gcc-patches@gcc.gnu.org Subject: [v3] plus Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 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 * include/bits/stl_function.h: Include for std::forward. (bit_not): New class. (plus, minus ,multiplies, divides, modulus, negate, equal_to, not_equal_to, greater, less, greater_equal, less_equal, logical_and, logical_or, logical_not, bit_and, bit_or, bit_xor, bit_not): New specializations. * testsuite/20_util/headers/functional/generic_function_objects.cc: New file. 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 // 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template struct negate : public unary_function<_Tp, _Tp> { _Tp operator()(const _Tp& __x) const { return -__x; } }; + +#if __cplusplus >= 201103L + template<> + struct negate + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template 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 + { + template + 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 + template struct logical_not : public unary_function<_Tp, bool> { bool operator()(const _Tp& __x) const { return !__x; } }; + +#if __cplusplus >= 201103L + template<> + struct logical_not + { + template + 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 + template struct bit_and : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x & __y; } }; - template +#if __cplusplus >= 201103L + template<> + struct bit_and + { + template + 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 struct bit_or : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x | __y; } }; - template +#if __cplusplus >= 201103L + template<> + struct bit_or + { + template + 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 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 + { + template + 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 + struct bit_not : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return ~__x; } + }; + +#if __cplusplus >= 201103L + template<> + struct bit_not + { + template + 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 +// . + +#include +#include + +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{} (a, B{})), + C >::value, "Meh?"); +static_assert (std::is_same< + decltype(std::bit_not{} (D{})), + E& >::value, "Bah...");