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

Reply via email to