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
This commit is contained in:
parent
13a26a7d10
commit
d081231ab5
|
@ -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
|
||||
|
|
|
@ -209,7 +209,7 @@ particular release.
|
|||
</link>
|
||||
</entry>
|
||||
<entry>Making Operator Functors greater<></entry>
|
||||
<entry>WIP</entry>
|
||||
<entry>Y</entry>
|
||||
<entry/>
|
||||
</row>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<>() );
|
Loading…
Reference in New Issue