On Wed, May 6, 2026 at 11:01 AM Jonathan Wakely <[email protected]> wrote:
> On Wed, 6 May 2026 at 08:57, Tomasz Kaminski <[email protected]> wrote: > > > > > > > > On Tue, May 5, 2026 at 5:04 PM Jonathan Wakely <[email protected]> > wrote: > >> > >> Clang 10 added support for concepts, so we no longer need to support > >> C++20 compilers that don't define __cpp_concepts. > >> > >> libstdc++-v3/ChangeLog: > >> > >> * include/bits/shared_ptr.h (_UnboundedArray, _BoundedArray) > >> (_NotUnboundedArray): Remove fallback definition for C++20 > >> compilers that don't define __cpp_concepts. > >> * include/bits/shared_ptr_base.h (_Sp_counted_ptr_inplace): > >> Remove fallback declaration of _Sp_overwrite_tag partial > >> specialization. > >> --- > >> > >> Tested x86_64-linux. > >> > >> libstdc++-v3/include/bits/shared_ptr.h | 18 ------------------ > >> libstdc++-v3/include/bits/shared_ptr_base.h | 5 ----- > >> 2 files changed, 23 deletions(-) > >> > >> diff --git a/libstdc++-v3/include/bits/shared_ptr.h > b/libstdc++-v3/include/bits/shared_ptr.h > >> index fd00384df223..ada32d3d3cb9 100644 > >> --- a/libstdc++-v3/include/bits/shared_ptr.h > >> +++ b/libstdc++-v3/include/bits/shared_ptr.h > >> @@ -114,38 +114,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > >> > >> #if __glibcxx_shared_ptr_arrays >= 201707L > >> // Constraint for overloads taking array types with unknown bound, > U[]. > >> -#if __cpp_concepts > >> template<typename _Tp> > >> requires is_array_v<_Tp> && (extent_v<_Tp> == 0) > >> using _UnboundedArray = _Tp; > > > > Could we replace this constrained alias with requires/concept on the > function? > > that are using it? This version was always deductible, so shouldn't make > difference. > > I wanted to do that, but just above this diff we have: > > // Constraint for overloads taking non-array types. > #if __cpp_concepts && __glibcxx_type_trait_variable_templates > template<typename _Tp> > requires (!is_array_v<_Tp>) > using _NonArray = _Tp; > #else > template<typename _Tp> > using _NonArray = __enable_if_t<!is_array<_Tp>::value, _Tp>; > #endif > > That *can't* use a requires-clause, it has to continue using a > constrained alias for C++11 mode. > > That means that std::make_shared and std::allocate_shared are > constrained using the alias: > > template<typename _Yp, typename _Alloc, typename... _Args> > friend shared_ptr<_NonArray<_Yp>> > allocate_shared(const _Alloc&, _Args&&...); > > template<typename _Yp, typename... _Args> > friend shared_ptr<_NonArray<_Yp>> > make_shared(_Args&&...); > > So for consistency I didn't want to change how the C++20 overloads are > defined: > > template<typename _Yp, typename _Alloc> > friend shared_ptr<_UnboundedArray<_Yp>> > allocate_shared(const _Alloc&, size_t); > > template<typename _Yp> > friend shared_ptr<_UnboundedArray<_Yp>> > make_shared(size_t); > > We could do it for the C++20 ones. I think it would still work > correctly to have the C++11 overloads constrained using the alias and > the later ones constrained using a requires-clause. The conditions > that enable each overload are mutually exclusive, so there would be no > concerns about the interaction between the different types of > constraints on overload resolution. There would still be exactly one > viable candidate for any given call. > > For make_shared_for_overwrite we don't have to worry about the > interaction with the C++11 overload, because there is no C++11 > overload. So we could change that to use a requires-clause, but it > would still look inconsistent with the related (not "_for_overwrite") > function templates. > > Also, because these make_shared* and allocate_shared* function > templates are all friends, if we use a requires-clause it needs to be > repeated in two places. > > So yes, it would be possible. I considered it, and decided to keep the > aliases (at least for now). > That makes sense, thanks for the detailed explanation.
