From: Jonathan Wakely Date: Fri, 1 Nov 2013 11:07:15 +0000 (+0000) Subject: N3421 C++1y Transparent functors X-Git-Tag: releases/gcc-4.9.0~3089 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d081231ab51048230fa2a083178b92d41aa8ac8f;p=thirdparty%2Fgcc.git N3421 C++1y Transparent functors N3421 C++1y Transparent functors * include/bits/stl_function.h (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): Define. * doc/xml/manual/status_cxx2014.xml: Update. * testsuite/20_util/function_objects/comparisons_void.cc: New. * include/bits/stl_function.h: Implement N3421. * testsuite/20_util/function_objects/comparisons_void.cc: New. From-SVN: r204290 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3309eb62455c..40d48794e21e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2013-11-01 Jonathan Wakely + + N3421 C++1y Transparent functors + * include/bits/stl_function.h (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): Define. + * doc/xml/manual/status_cxx2014.xml: Update. + * testsuite/20_util/function_objects/comparisons_void.cc: New. + 2013-10-31 Jonathan Wakely * include/std/tuple (_Index_tuple, _Build_index_tuple): Move to diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2014.xml b/libstdc++-v3/doc/xml/manual/status_cxx2014.xml index 4ef4334ab348..b368a810e6a7 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2014.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2014.xml @@ -209,7 +209,7 @@ particular release. Making Operator Functors greater<> - WIP + Y diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h index 23529dff30cf..d2e5d1346639 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 +#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 + struct plus; + + template + struct minus; + + template + struct multiplies; + + template + struct divides; + + template + struct modulus; + + template + struct negate; +#endif + /// One of the @link arithmetic_functors math functors@endlink. template struct plus : public binary_function<_Tp, _Tp, _Tp> @@ -188,6 +215,91 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(const _Tp& __x) const { return -__x; } }; + +#if __cplusplus > 201103L + template<> + struct plus + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) + std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) - std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) * std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) / std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) % std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t) const + noexcept(noexcept(-std::forward<_Tp>(__t))) + -> decltype(-std::forward<_Tp>(__t)) + { return -std::forward<_Tp>(__t); } + + typedef __is_transparent is_transparent; + }; +#endif /** @} */ // 20.3.3 comparisons @@ -199,6 +311,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * @{ */ +#if __cplusplus > 201103L + template + struct equal_to; + + template + struct not_equal_to; + + template + struct greater; + + template + struct less; + + template + struct greater_equal; + + template + struct less_equal; +#endif + /// One of the @link comparison_functors comparison functors@endlink. template struct equal_to : public binary_function<_Tp, _Tp, bool> @@ -252,6 +384,92 @@ _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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) != std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) > std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) >= std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) <= std::forward<_Up>(__u))) + -> 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 +481,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * @{ */ +#if __cplusplus > 201103L + template + struct logical_and; + + template + struct logical_or; + + template + struct logical_not; +#endif + /// One of the @link logical_functors Boolean operations functors@endlink. template struct logical_and : public binary_function<_Tp, _Tp, bool> @@ -289,8 +518,64 @@ _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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) && std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) || std::forward<_Up>(__u))) + -> 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 + { + template + 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 + struct bit_and; + + template + struct bit_or; + + template + struct bit_xor; + + template + struct bit_not; +#endif + // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 660. Missing Bitwise Operations. template @@ -317,6 +602,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __x ^ __y; } }; + template + struct bit_not : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return ~__x; } + }; + +#if __cplusplus > 201103L + template <> + struct bit_and + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) & std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) | std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u))) + -> 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 + { + template + auto + operator()(_Tp&& __t) const + noexcept(noexcept(~std::forward<_Tp>(__t))) + -> 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 000000000000..2cea1fc8dfd5 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/comparisons_void.cc @@ -0,0 +1,95 @@ +// { 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 +// . + +// 20.3.3 Comparisons + +#include + +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; } + + bool operator&&(const R&) const { return true; } + bool operator||(const R&) const { return true; } + bool operator!() const { return false; } + + int operator&(const R&) const { return 1; } + int operator|(const R&) const { return 1; } + int operator^(const R&) const { return 0; } + int operator~() const { return 0; } +}; + +L l; +R r; + +// test unary function objects +template +bool +test1(F f) +{ + f(l); + return true; +} + +// test binary function objects +template +bool +test2(F f) +{ + f(l, r); + return true; +} + +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<>() );