+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.
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
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;
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)
{
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;
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);
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));
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);
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));
__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;
--- /dev/null
+// 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({});
+}
--- /dev/null
+// 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({});
+}