nonesuch is insufficiently useless (lwg2996)

2019-05-14  Nina Dinka Ranns  <dinka.ranns@gmail.com>

	nonesuch is insufficiently useless (lwg2996)
	* include/std/type_traits (struct __nonesuch): Added private base
	class to make __nonesuch not an aggregate and removed deleted default
	constructor.
	* include/bits/stl_pair.h (struct __nonesuch_no_braces): Removed.
	(operator=(const pair&)): Use __nonesuch instead of
	__nonesuch_no_braces.
	(operator=(pair&&)): Likewise
	* include/std/tuple (operator=(const tuple&)): Use __nonesuch instead
	of __nonesuch_no_braces.
	(operator=(tuple&&)): Likewise
	* include/experimental/type_traits (struct nonesuch): Added private
	base class to make nonesuch not an aggregate and removed deleted
	default constructor.
	* testsuite/20_util/nonesuch/nonesuch.cc: New.
	* testsuite/experimental/type_traits/nonesuch.cc: New.

From-SVN: r271175
This commit is contained in:
Nina Dinka Ranns 2019-05-14 15:48:27 +00:00 committed by Jonathan Wakely
parent 330b17474c
commit a73d2fa852
7 changed files with 108 additions and 17 deletions

View File

@ -1,3 +1,22 @@
2019-05-14 Nina Dinka Ranns <dinka.ranns@gmail.com>
nonesuch is insufficiently useless (lwg2996)
* include/std/type_traits (struct __nonesuch): Added private base
class to make __nonesuch not an aggregate and removed deleted default
constructor.
* include/bits/stl_pair.h (struct __nonesuch_no_braces): Removed.
(operator=(const pair&)): Use __nonesuch instead of
__nonesuch_no_braces.
(operator=(pair&&)): Likewise
* include/std/tuple (operator=(const tuple&)): Use __nonesuch instead
of __nonesuch_no_braces.
(operator=(tuple&&)): Likewise
* include/experimental/type_traits (struct nonesuch): Added private
base class to make nonesuch not an aggregate and removed deleted
default constructor.
* testsuite/20_util/nonesuch/nonesuch.cc: New.
* testsuite/experimental/type_traits/nonesuch.cc: New.
2019-05-14 Jonathan Wakely <jwakely@redhat.com>
* include/bits/std_function.h (_Simple_type_wrapper): Remove.

View File

@ -180,13 +180,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
};
// PR libstdc++/79141, a utility type for preventing
// initialization of an argument of a disabled assignment
// operator from a pair of empty braces.
struct __nonesuch_no_braces : std::__nonesuch {
explicit __nonesuch_no_braces(const __nonesuch&) = delete;
};
#endif // C++11
template<typename _U1, typename _U2> class __pair_base
@ -393,7 +386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator=(typename conditional<
__and_<is_copy_assignable<_T1>,
is_copy_assignable<_T2>>::value,
const pair&, const __nonesuch_no_braces&>::type __p)
const pair&, const __nonesuch&>::type __p)
{
first = __p.first;
second = __p.second;
@ -404,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator=(typename conditional<
__and_<is_move_assignable<_T1>,
is_move_assignable<_T2>>::value,
pair&&, __nonesuch_no_braces&&>::type __p)
pair&&, __nonesuch&&>::type __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{

View File

@ -227,9 +227,9 @@ inline namespace fundamentals_v2
template<typename...> using void_t = void;
struct nonesuch
struct __nonesuchbase {};
struct nonesuch : private __nonesuchbase
{
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
void operator=(nonesuch const&) = delete;

View File

@ -832,7 +832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple&
operator=(typename conditional<__assignable<const _Elements&...>(),
const tuple&,
const __nonesuch_no_braces&>::type __in)
const __nonesuch&>::type __in)
noexcept(__nothrow_assignable<const _Elements&...>())
{
this->_M_assign(__in);
@ -842,7 +842,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple&
operator=(typename conditional<__assignable<_Elements...>(),
tuple&&,
__nonesuch_no_braces&&>::type __in)
__nonesuch&&>::type __in)
noexcept(__nothrow_assignable<_Elements...>())
{
this->_M_assign(std::move(__in));
@ -1243,7 +1243,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple&
operator=(typename conditional<__assignable<const _T1&, const _T2&>(),
const tuple&,
const __nonesuch_no_braces&>::type __in)
const __nonesuch&>::type __in)
noexcept(__nothrow_assignable<const _T1&, const _T2&>())
{
this->_M_assign(__in);
@ -1253,7 +1253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple&
operator=(typename conditional<__assignable<_T1, _T2>(),
tuple&&,
__nonesuch_no_braces&&>::type __in)
__nonesuch&&>::type __in)
noexcept(__nothrow_assignable<_T1, _T2>())
{
this->_M_assign(std::move(__in));

View File

@ -2792,8 +2792,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__call_is_nothrow_<_Fn, _Args...>>::type
{ };
struct __nonesuch {
__nonesuch() = delete;
struct __nonesuchbase {};
struct __nonesuch : private __nonesuchbase {
~__nonesuch() = delete;
__nonesuch(__nonesuch const&) = delete;
void operator=(__nonesuch const&) = delete;

View File

@ -0,0 +1,39 @@
// 2019-05-14 Nina Dinka Ranns <dinka.ranns@gmail.com>
// 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-do compile { target c++14 } }
#include <type_traits>
// Example taken from LWG2960
using std::__nonesuch;
struct such {};
void f(const such&){};
void f(const std::__nonesuch&);
int main(){
static_assert(!std::is_default_constructible<__nonesuch>::value,
"__nonesuch is default constructible");
static_assert(!std::is_copy_constructible<__nonesuch>::value,
"__nonesuch is copy constructible");
static_assert(!std::is_assignable<__nonesuch, __nonesuch>::value,
"__nonesuch is assignable");
static_assert(!std::is_destructible<__nonesuch>::value,
"__nonesuch is destructible");
f({});
}

View File

@ -0,0 +1,40 @@
// 2019-05-14 Nina Dinka Ranns <dinka.ranns@gmail.com>
// 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-do compile { target c++14 } }
#include <experimental/type_traits>
// Example taken from LWG2960
using std::experimental::nonesuch;
struct such {};
void f(const such&){};
void f(const nonesuch&);
int main(){
static_assert(!std::is_default_constructible<nonesuch>::value,
"nonesuch is default constructible");
static_assert(!std::is_copy_constructible<nonesuch>::value,
"nonesuch is copy constructible");
static_assert(!std::is_assignable<nonesuch,nonesuch>::value,
"nonesuch is assignable");
static_assert(!std::is_destructible<nonesuch>::value,
"nonesuch is destructible");
f({});
}