diff options
author | Jonathan Wakely <jwakely.gcc@gmail.com> | 2013-11-01 11:07:15 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2013-11-01 11:07:15 +0000 |
commit | d081231ab51048230fa2a083178b92d41aa8ac8f (patch) | |
tree | 655f442bb1d1be9cf328d00f9b386e0e15fdcaac /libstdc++-v3 | |
parent | 13a26a7d10c7beb64dcdb8c41d6c4b1d81a1a271 (diff) | |
download | gcc-d081231ab51048230fa2a083178b92d41aa8ac8f.tar.gz |
N3421 C++1y Transparent functors
N3421 C++1y Transparent functors
* include/bits/stl_function.h (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>): 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
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/status_cxx2014.xml | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_function.h | 347 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/function_objects/comparisons_void.cc | 95 |
4 files changed, 455 insertions, 1 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3309eb62455..40d48794e21 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2013-11-01 Jonathan Wakely <jwakely.gcc@gmail.com> + + N3421 C++1y Transparent functors + * include/bits/stl_function.h (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>): Define. + * doc/xml/manual/status_cxx2014.xml: Update. + * testsuite/20_util/function_objects/comparisons_void.cc: New. + 2013-10-31 Jonathan Wakely <jwakely.gcc@gmail.com> * 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 4ef4334ab34..b368a810e6a 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. </link> </entry> <entry>Making Operator Functors greater<></entry> - <entry>WIP</entry> + <entry>Y</entry> <entry/> </row> diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h index 23529dff30c..d2e5d134663 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,91 @@ _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 + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp> + 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<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 +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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<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 +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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<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 +602,68 @@ _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 + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp, typename _Up> + 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<void> + { + template <typename _Tp> + 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 00000000000..2cea1fc8dfd --- /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 +// <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; } + + 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<typename F, typename Check = typename F::is_transparent> +bool +test1(F f) +{ + f(l); + return true; +} + +// test binary function objects +template<typename F, typename Check = typename F::is_transparent> +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<>() ); |