On Thu, 29 Oct 2020, Patrick Palka wrote: > The class template semiregular-box<T> of [range.semi.wrap] is specified > to value-initialize the underlying object whenever its type is default- > initializable. Our primary template for __detail::__box respects this > requirement, but the recently added partial specialization (for types > which are already semiregular) does not. > > This patch fixes this issue, and additionally makes the in place > constructor explicit (as in the primary template). > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk? > > libstdc++-v3/ChangeLog: > > * include/std/ranges (__detail::__box): For the partial > specialization for types that are already semiregular, > make the default constructor value-initialize the underlying > object instead of default-initializing it. Make the > corresponding in place constructor explicit. > * testsuite/std/ranges/detail/semiregular_box.cc: New test. > --- > libstdc++-v3/include/std/ranges | 4 +-- > .../std/ranges/detail/semiregular_box.cc | 33 +++++++++++++++++++ > 2 files changed, 35 insertions(+), 2 deletions(-) > create mode 100644 > libstdc++-v3/testsuite/std/ranges/detail/semiregular_box.cc > > diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges > index df02b03cada..59aac326309 100644 > --- a/libstdc++-v3/include/std/ranges > +++ b/libstdc++-v3/include/std/ranges > @@ -141,7 +141,7 @@ namespace ranges > struct __box<_Tp> > { > private: > - [[no_unique_address]] _Tp _M_value; > + [[no_unique_address]] _Tp _M_value = {};
It would be more consistent with the rest of the header to do = _Tp() instead: Tested on x86_64-pc-linux-gnu. -- >8 -- --- libstdc++-v3/include/std/ranges | 4 +-- .../std/ranges/detail/semiregular_box.cc | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 libstdc++-v3/testsuite/std/ranges/detail/semiregular_box.cc diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index df02b03cada..579280d16fb 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -141,7 +141,7 @@ namespace ranges struct __box<_Tp> { private: - [[no_unique_address]] _Tp _M_value; + [[no_unique_address]] _Tp _M_value = _Tp(); public: __box() = default; @@ -160,7 +160,7 @@ namespace ranges template<typename... _Args> requires constructible_from<_Tp, _Args...> - constexpr + constexpr explicit __box(in_place_t, _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>) : _M_value{std::forward<_Args>(__args)...} diff --git a/libstdc++-v3/testsuite/std/ranges/detail/semiregular_box.cc b/libstdc++-v3/testsuite/std/ranges/detail/semiregular_box.cc new file mode 100644 index 00000000000..2a909d6ae50 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/detail/semiregular_box.cc @@ -0,0 +1,33 @@ +// 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++2a" } +// { dg-do compile { target c++2a } } + +#include <ranges> + +using std::ranges::__detail::__box; + +constexpr bool +test01() +{ + // Verify the default constructor value-initializes the underlying object. + __box<int> x; + __glibcxx_assert(*x == 0); + return true; +} +static_assert(test01()); -- 2.29.0.rc0