mirror of git://gcc.gnu.org/git/gcc.git
Make std::experimental::not_fn SFINAE-friendly.
PR libstdc++/66998 * include/experimental/functional (_Not_fn): Add exception specifications and non-deduced return types. (not_fn): Add exception specification and wrap pointer-to-member. * testsuite/experimental/functional/not_fn.cc: Test in SFINAE context and test pointer-to-member. From-SVN: r227448
This commit is contained in:
parent
500dc9a6c3
commit
eb8bf686b7
|
|
@ -1,5 +1,12 @@
|
||||||
2015-09-03 Jonathan Wakely <jwakely@redhat.com>
|
2015-09-03 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/66998
|
||||||
|
* include/experimental/functional (_Not_fn): Add exception
|
||||||
|
specifications and non-deduced return types.
|
||||||
|
(not_fn): Add exception specification and wrap pointer-to-member.
|
||||||
|
* testsuite/experimental/functional/not_fn.cc: Test in SFINAE context
|
||||||
|
and test pointer-to-member.
|
||||||
|
|
||||||
PR libstdc++/62039
|
PR libstdc++/62039
|
||||||
* include/bits/stl_iterator_base_funcs.h (next, prev): Add concept
|
* include/bits/stl_iterator_base_funcs.h (next, prev): Add concept
|
||||||
checks.
|
checks.
|
||||||
|
|
|
||||||
|
|
@ -376,8 +376,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
/// Generalized negator.
|
/// Generalized negator.
|
||||||
template<typename _Fn>
|
template<typename _Fn>
|
||||||
struct _Not_fn
|
class _Not_fn
|
||||||
{
|
{
|
||||||
|
_Fn _M_fn;
|
||||||
|
|
||||||
|
public:
|
||||||
template<typename _Fn2>
|
template<typename _Fn2>
|
||||||
explicit
|
explicit
|
||||||
_Not_fn(_Fn2&& __fn) : _M_fn(std::forward<_Fn2>(__fn)) { }
|
_Not_fn(_Fn2&& __fn) : _M_fn(std::forward<_Fn2>(__fn)) { }
|
||||||
|
|
@ -389,34 +392,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
~_Not_fn() = default;
|
~_Not_fn() = default;
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
decltype(auto)
|
auto
|
||||||
operator()(_Args&&... __args)
|
operator()(_Args&&... __args)
|
||||||
|
noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
|
||||||
|
-> decltype(!_M_fn(std::forward<_Args>(__args)...))
|
||||||
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
decltype(auto)
|
auto
|
||||||
operator()(_Args&&... __args) const
|
operator()(_Args&&... __args) const
|
||||||
|
noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
|
||||||
|
-> decltype(!_M_fn(std::forward<_Args>(__args)...))
|
||||||
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
decltype(auto)
|
auto
|
||||||
operator()(_Args&&... __args) volatile
|
operator()(_Args&&... __args) volatile
|
||||||
|
noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
|
||||||
|
-> decltype(!_M_fn(std::forward<_Args>(__args)...))
|
||||||
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
decltype(auto)
|
auto
|
||||||
operator()(_Args&&... __args) const volatile
|
operator()(_Args&&... __args) const volatile
|
||||||
|
noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
|
||||||
|
-> decltype(!_M_fn(std::forward<_Args>(__args)...))
|
||||||
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
{ return !_M_fn(std::forward<_Args>(__args)...); }
|
||||||
|
|
||||||
private:
|
|
||||||
_Fn _M_fn;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// [func.not_fn] Function template not_fn
|
/// [func.not_fn] Function template not_fn
|
||||||
template <class _Fn>
|
template<typename _Fn>
|
||||||
inline auto
|
inline auto
|
||||||
not_fn(_Fn&& __fn)
|
not_fn(_Fn&& __fn)
|
||||||
{ return _Not_fn<std::decay_t<_Fn>>{std::forward<_Fn>(__fn)}; }
|
noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value)
|
||||||
|
{
|
||||||
|
using __maybe_type = _Maybe_wrap_member_pointer<std::decay_t<_Fn>>;
|
||||||
|
return _Not_fn<typename __maybe_type::type>{std::forward<_Fn>(__fn)};
|
||||||
|
}
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_VERSION
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
} // namespace fundamentals_v2
|
} // namespace fundamentals_v2
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
#include <experimental/functional>
|
#include <experimental/functional>
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
using std::experimental::not_fn;
|
||||||
|
|
||||||
int func(int, char) { return 0; }
|
int func(int, char) { return 0; }
|
||||||
|
|
||||||
struct F
|
struct F
|
||||||
|
|
@ -33,8 +35,6 @@ struct F
|
||||||
void
|
void
|
||||||
test01()
|
test01()
|
||||||
{
|
{
|
||||||
using std::experimental::not_fn;
|
|
||||||
|
|
||||||
auto f1 = not_fn(func);
|
auto f1 = not_fn(func);
|
||||||
VERIFY( f1(1, '2') == true );
|
VERIFY( f1(1, '2') == true );
|
||||||
|
|
||||||
|
|
@ -50,8 +50,36 @@ test01()
|
||||||
VERIFY( f5(1) == false );
|
VERIFY( f5(1) == false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename F, typename Arg>
|
||||||
|
auto foo(F f, Arg arg) -> decltype(not_fn(f)(arg)) { return not_fn(f)(arg); }
|
||||||
|
|
||||||
|
template<typename F, typename Arg>
|
||||||
|
auto foo(F f, Arg arg) -> decltype(not_fn(f)()) { return not_fn(f)(); }
|
||||||
|
|
||||||
|
struct negator
|
||||||
|
{
|
||||||
|
bool operator()(int) const { return false; }
|
||||||
|
void operator()() const {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
test02()
|
||||||
|
{
|
||||||
|
foo(negator{}, 1); // PR libstdc++/66998
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test03()
|
||||||
|
{
|
||||||
|
struct X { bool b; };
|
||||||
|
X x{ false };
|
||||||
|
VERIFY( not_fn(&X::b)(x) );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
|
test02();
|
||||||
|
test03();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue