P1651R0 bind_front should not unwrap reference_wrapper
P1651R0 bind_front should not unwrap reference_wrapper * include/std/functional (bind_front): Don't unwrap reference_wrapper. * include/std/version (__cpp_lib_bind_front): Update value. * testsuite/20_util/function_objects/bind_front/1.cc: Fix test for feature test macro. * testsuite/20_util/function_objects/bind_front/2.cc: New test. From-SVN: r274146
This commit is contained in:
parent
a38b51bc3a
commit
ffc500dd41
5 changed files with 102 additions and 4 deletions
|
@ -1,5 +1,12 @@
|
|||
2019-08-06 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
P1651R0 bind_front should not unwrap reference_wrapper
|
||||
* include/std/functional (bind_front): Don't unwrap reference_wrapper.
|
||||
* include/std/version (__cpp_lib_bind_front): Update value.
|
||||
* testsuite/20_util/function_objects/bind_front/1.cc: Fix test for
|
||||
feature test macro.
|
||||
* testsuite/20_util/function_objects/bind_front/2.cc: New test.
|
||||
|
||||
* include/std/numbers [!__STRICT_ANSI__ && _GLIBCXX_USE_FLOAT128]
|
||||
(e_v, log2e_v, log10e_v, pi_v, inv_pi_v, inv_sqrtpi_v, ln2_v, ln10_v)
|
||||
(sqrt2_v, sqrt3_v, inv_sqrt3, egamma_v, phi_v): Add explicit
|
||||
|
|
|
@ -791,7 +791,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
}
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
#define __cpp_lib_bind_front 201902L
|
||||
#define __cpp_lib_bind_front 201907L
|
||||
|
||||
template<typename _Fd, typename... _BoundArgs>
|
||||
struct _Bind_front
|
||||
|
@ -877,7 +877,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
template<typename _Fn, typename... _Args>
|
||||
using _Bind_front_t
|
||||
= _Bind_front<decay_t<_Fn>, unwrap_ref_decay_t<_Args>...>;
|
||||
= _Bind_front<decay_t<_Fn>, decay_t<_Args>...>;
|
||||
|
||||
template<typename _Fn, typename... _Args>
|
||||
_Bind_front_t<_Fn, _Args...>
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
#if __cplusplus > 201703L
|
||||
// c++2a
|
||||
#define __cpp_lib_atomic_ref 201806L
|
||||
#define __cpp_lib_bind_front 201902L
|
||||
#define __cpp_lib_bind_front 201907L
|
||||
#define __cpp_lib_bounded_array_traits 201902L
|
||||
#if __cpp_impl_destroying_delete
|
||||
# define __cpp_lib_destroying_delete 201806L
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#ifndef __cpp_lib_bind_front
|
||||
# error "Feature test macro for bind_front is missing"
|
||||
#elif __cpp_lib_bind_front < 201811L
|
||||
#elif __cpp_lib_bind_front < 201902L
|
||||
# error "Feature test macro for bind_front has wrong value"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (C) 2019 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// P1651R0 bind_front should not unwrap reference_wrapper
|
||||
|
||||
#ifndef __cpp_lib_bind_front
|
||||
# error "Feature test macro for bind_front is missing"
|
||||
#elif __cpp_lib_bind_front < 201907L
|
||||
# error "Feature test macro for bind_front has wrong value"
|
||||
#endif
|
||||
|
||||
void functionAcceptingStringView(std::string_view) { }
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
std::string s;
|
||||
auto fs = std::bind_front(&functionAcceptingStringView, std::string_view(s));
|
||||
fs();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
struct PartialApply {
|
||||
PartialApply(F f) : f(f) {}
|
||||
F f;
|
||||
|
||||
template <typename... A> decltype(auto) operator()(A const&... a) const {
|
||||
if constexpr (std::is_invocable<F const&, A const&...>::value) {
|
||||
return f(a...);
|
||||
} else {
|
||||
return bind_front(*this, a...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
struct Thingy { };
|
||||
std::unique_ptr<Thingy> thingy;
|
||||
auto func = [](const std::unique_ptr<Thingy>&, int) {};
|
||||
PartialApply{func}(std::ref(thingy))(10);
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
std::string str;
|
||||
auto func = [](const std::string& s, int) -> const std::string& { return s; };
|
||||
|
||||
// sref refers to copy of str stored in bind_front result:
|
||||
const std::string& sref = PartialApply{func}(std::ref(str))(10);
|
||||
|
||||
// pre-P1651R0 this is a use of a dangling reference:
|
||||
const char& c = sref[0];
|
||||
|
||||
// post-P1651R0 the bind_front result stores a reference_wrapper by value,
|
||||
// and so sref is bound to str instead of dangling:
|
||||
VERIFY( &c == str.data() );
|
||||
VERIFY( &sref == &str );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
Loading…
Add table
Reference in a new issue