On Tue, 5 Dec 2023, Jonathan Wakely wrote: > On Wed, 22 Nov 2023 at 14:50, Jonathan Wakely <jwak...@redhat.com> wrote: > > > > On Mon, 20 Nov 2023 at 02:56, Jason Merrill wrote: > > > > > > Tested x86_64-pc-linux-gnu. Are the library bits OK? Any comments > > > before I > > > push this? > > > > The library parts are OK. > > > > The variable template is_trivially_copyable_v just uses > > __is_trivially_copyable so should be just as efficient, and the change > > to <bit> is fine. > > > > The variable template is_trivially_destructible_v instantiates the > > is_trivially_destructible type trait, which instantiates > > __is_destructible_safe and __is_destructible_impl, which is probably > > why we used the built-in directly in <variant>. But that's an > > acceptable overhead to avoid using the built-in in a mangled context, > > and it would be good to optimize the variable template anyway, as a > > separate change. > > This actually causes a regression: > > FAIL: 20_util/variant/87619.cc -std=gnu++20 (test for excess errors) > FAIL: 20_util/variant/87619.cc -std=gnu++23 (test for excess errors) > FAIL: 20_util/variant/87619.cc -std=gnu++26 (test for excess errors) > > It's OK for C++17 because the changed code is only used for C++20 and later. > > That test instantiates a very large variant to check that we don't hit > our template instantiation depth limit. Using the variable template > (which uses the class template) instead of the built-in causes it to > fail now.
Could we pass down __trivially_destructible from _Variadic_storage to _Variadic_union and use that as the dtor's constraint instead of recursively re-computing it? This reduces the maximum template instantiation depth for 87619.cc to ~270 from ~780 so that the depth is roughly #variants rather than 4 * #variants. diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 20a76c8aa87..4b9002e0917 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -392,7 +392,7 @@ namespace __variant }; // Defines members and ctors. - template<typename... _Types> + template<bool __trivially_destructible, typename... _Types> union _Variadic_union { _Variadic_union() = default; @@ -401,8 +401,8 @@ namespace __variant _Variadic_union(in_place_index_t<_Np>, _Args&&...) = delete; }; - template<typename _First, typename... _Rest> - union _Variadic_union<_First, _Rest...> + template<bool __trivially_destructible, typename _First, typename... _Rest> + union _Variadic_union<__trivially_destructible, _First, _Rest...> { constexpr _Variadic_union() : _M_rest() { } @@ -427,13 +427,12 @@ namespace __variant ~_Variadic_union() = default; constexpr ~_Variadic_union() - requires (!is_trivially_destructible_v<_First>) - || (!is_trivially_destructible_v<_Variadic_union<_Rest...>>) + requires (!__trivially_destructible) { } #endif _Uninitialized<_First> _M_first; - _Variadic_union<_Rest...> _M_rest; + _Variadic_union<__trivially_destructible, _Rest...> _M_rest; }; // _Never_valueless_alt is true for variant alternatives that can @@ -514,7 +513,7 @@ namespace __variant return this->_M_index != __index_type(variant_npos); } - _Variadic_union<_Types...> _M_u; + _Variadic_union<false, _Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; @@ -552,7 +551,7 @@ namespace __variant return this->_M_index != static_cast<__index_type>(variant_npos); } - _Variadic_union<_Types...> _M_u; + _Variadic_union<true, _Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; > > So optimizing the variable template is now a priority. > >