libstdc++: Fix up semiregular-box partial specialization [PR100475]

This makes the in-place constructor of our partial specialization of
__box for already-semiregular types perform direct-non-list-initialization
(in accordance with the specification of the primary template), and
additionally makes the member function data() use std::__addressof.

libstdc++-v3/ChangeLog:

	PR libstdc++/100475
	* include/std/ranges (__box::__box): Use non-list-initialization
	in member initializer list of in-place constructor of the
	partial specialization for semiregular types.
	(__box::operator->): Use std::__addressof.
	* testsuite/std/ranges/adaptors/detail/semiregular_box.cc
	(test02): New test.
	* testsuite/std/ranges/single_view.cc (test04): New test.
This commit is contained in:
Patrick Palka 2021-05-18 00:28:44 -04:00
parent 03cf8d54e5
commit fe993b469c
3 changed files with 37 additions and 3 deletions

View File

@ -163,7 +163,7 @@ namespace ranges
constexpr explicit
__box(in_place_t, _Args&&... __args)
noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
: _M_value{std::forward<_Args>(__args)...}
: _M_value(std::forward<_Args>(__args)...)
{ }
constexpr bool
@ -180,11 +180,11 @@ namespace ranges
constexpr _Tp*
operator->() noexcept
{ return &_M_value; }
{ return std::__addressof(_M_value); }
constexpr const _Tp*
operator->() const noexcept
{ return &_M_value; }
{ return std::__addressof(_M_value); }
};
} // namespace __detail

View File

@ -81,3 +81,21 @@ test01()
return true;
}
static_assert(test01());
template<bool make_semiregular>
struct A {
A() requires make_semiregular;
A(int, int);
A(std::initializer_list<int>) = delete;
};
void
test02()
{
// PR libstdc++/100475
static_assert(std::semiregular<A<true>>);
__box<A<true>> x2(std::in_place, 0, 0);
static_assert(!std::semiregular<A<false>>);
__box<A<false>> x1(std::in_place, 0, 0);
}

View File

@ -58,9 +58,25 @@ test03()
VERIFY(*std::ranges::begin(s3) == 'a');
}
void
test04()
{
// PR libstdc++/100475
struct A {
A() = default;
A(int, int) { }
A(std::initializer_list<int>) = delete;
void operator&() const = delete;
};
std::ranges::single_view<A> s(std::in_place, 0, 0);
s.data();
std::as_const(s).data();
}
int main()
{
test01();
test02();
test03();
test04();
}