2020-03-18 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/94033
+ * include/std/type_traits (__is_nt_default_constructible_atom): Remove.
+ (__is_nt_default_constructible_impl): Remove.
+ (__is_nothrow_default_constructible_impl): Remove.
+ (__is_nt_constructible_impl): Add bool template parameter. Adjust
+ partial specializations.
+ (__is_nothrow_constructible_impl): Replace class template with alias
+ template.
+ (is_nothrow_default_constructible): Derive from alias template
+ __is_nothrow_constructible_impl instead of
+ __is_nothrow_default_constructible_impl.
+ * testsuite/20_util/is_nothrow_constructible/94003.cc: New test.
+
* include/std/stop_token (stop_token::_Stop_state_ref): Define
comparison operators explicitly if the compiler won't synthesize them.
"template argument must be a complete class or an unbounded array");
};
- template<typename _Tp>
- struct __is_nt_default_constructible_atom
- : public integral_constant<bool, noexcept(_Tp())>
- { };
-
- template<typename _Tp, bool = is_array<_Tp>::value>
- struct __is_nt_default_constructible_impl;
-
- template<typename _Tp>
- struct __is_nt_default_constructible_impl<_Tp, true>
- : public __and_<__is_array_known_bounds<_Tp>,
- __is_nt_default_constructible_atom<typename
- remove_all_extents<_Tp>::type>>
- { };
-
- template<typename _Tp>
- struct __is_nt_default_constructible_impl<_Tp, false>
- : public __is_nt_default_constructible_atom<_Tp>
+ template<bool, typename _Tp, typename... _Args>
+ struct __is_nt_constructible_impl
+ : public false_type
{ };
- template<typename _Tp>
- using __is_nothrow_default_constructible_impl
- = __and_<__is_constructible_impl<_Tp>,
- __is_nt_default_constructible_impl<_Tp>>;
-
- /// is_nothrow_default_constructible
- template<typename _Tp>
- struct is_nothrow_default_constructible
- : public __is_nothrow_default_constructible_impl<_Tp>::type
- {
- static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
- "template argument must be a complete class or an unbounded array");
- };
-
template<typename _Tp, typename... _Args>
- struct __is_nt_constructible_impl
- : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
+ struct __is_nt_constructible_impl<true, _Tp, _Args...>
+ : public __bool_constant<noexcept(_Tp(std::declval<_Args>()...))>
{ };
template<typename _Tp, typename _Arg>
- struct __is_nt_constructible_impl<_Tp, _Arg>
- : public integral_constant<bool,
- noexcept(static_cast<_Tp>(declval<_Arg>()))>
+ struct __is_nt_constructible_impl<true, _Tp, _Arg>
+ : public __bool_constant<noexcept(static_cast<_Tp>(std::declval<_Arg>()))>
{ };
template<typename _Tp>
- struct __is_nt_constructible_impl<_Tp>
- : public __is_nothrow_default_constructible_impl<_Tp>
+ struct __is_nt_constructible_impl<true, _Tp>
+ : public __bool_constant<noexcept(_Tp())>
{ };
- template<typename _Tp, typename... _Args>
- struct __is_nothrow_constructible_impl
- : public __and_<__is_constructible_impl<_Tp, _Args...>,
- __is_nt_constructible_impl<_Tp, _Args...>>
+ template<typename _Tp, size_t _Num>
+ struct __is_nt_constructible_impl<true, _Tp[_Num]>
+ : public __bool_constant<noexcept(typename remove_all_extents<_Tp>::type())>
{ };
+ template<typename _Tp, typename... _Args>
+ using __is_nothrow_constructible_impl
+ = __is_nt_constructible_impl<__is_constructible(_Tp, _Args...),
+ _Tp, _Args...>;
+
/// is_nothrow_constructible
template<typename _Tp, typename... _Args>
struct is_nothrow_constructible
"template argument must be a complete class or an unbounded array");
};
+ /// is_nothrow_default_constructible
+ template<typename _Tp>
+ struct is_nothrow_default_constructible
+ : public __is_nothrow_constructible_impl<_Tp>::type
+ {
+ static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
+ "template argument must be a complete class or an unbounded array");
+ };
+
+
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
struct __is_nothrow_copy_constructible_impl;
--- /dev/null
+// Copyright (C) 2020 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++17" }
+// { dg-do compile { target c++17 } }
+
+#include <optional>
+#include <tuple>
+
+template <bool B> struct abc {};
+
+template <typename T>
+
+struct future : public abc<std::is_trivially_constructible_v<std::tuple<T>>> {};
+
+class mutation {
+ mutation();
+ friend class std::optional<mutation>;
+};
+
+using mutation_opt = std::optional<mutation>;
+
+future<mutation_opt> foo();
+
+template <typename Consumer> future<mutation_opt> consume_partitions() {
+ return foo();
+}
+
+future<mutation_opt> bar() { return consume_partitions<int>(); }
+
+future<mutation> zed();
+future<mutation> apply_counter_update() { return zed(); }