This implements the wording changes of P2367R0 "Remove misuses of
list-initialization from Clause 24", modulo the parts that depend
on P1739R4 which we don't yet implement (due to LWG 3407).

Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

libstdc++-v3/ChangeLog:

        * include/bits/ranges_util.h (subrange::subrange): Avoid
        list-initialization in delegating constructor.
        * include/std/ranges (single_view): Replace implicit guide
        with explicit deduction guide that decays its argument.
        (_Single::operator()): Avoid CTAD when constructing the
        single_view object.
        (_Iota::operator()): Avoid list-initialization.
        (__detail::__can_filter_view, _Filter::operator()): Likewise.
        (__detail::__can_transform_view, _Transform::operator()): Likewise.
        (take_view::begin): Likewise.
        (__detail::__can_take_view, _Take::operator()): Likewise.
        (__detail::__can_take_while_view, _TakeWhile::operator()): Likewise.
        (__detail::__can_drop_view, _Drop::operator()): Likewise.
        (__detail::__can_drop_while_view, _DropWhile::operator()): Likewise.
        (split_view::split_view): Use views::single when initializing
        _M_pattern.
        (__detail::__can_split_view, _Split::operator()): Avoid
        list-initialization.
        (_Counted::operator()): Likewise.
        * testsuite/std/ranges/p2367.cc: New test.
---
 libstdc++-v3/include/bits/ranges_util.h    |  2 +-
 libstdc++-v3/include/std/ranges            | 55 ++++++++++++----------
 libstdc++-v3/testsuite/std/ranges/p2367.cc | 48 +++++++++++++++++++
 3 files changed, 78 insertions(+), 27 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/ranges/p2367.cc

diff --git a/libstdc++-v3/include/bits/ranges_util.h 
b/libstdc++-v3/include/bits/ranges_util.h
index 9d51e1b874e..589886eb157 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -251,7 +251,7 @@ namespace ranges
          && convertible_to<sentinel_t<_Rng>, _Sent>
        constexpr
        subrange(_Rng&& __r) requires (!_S_store_size)
-       : subrange{ranges::begin(__r), ranges::end(__r)}
+       : subrange(ranges::begin(__r), ranges::end(__r))
        { }
 
       template<borrowed_range _Rng>
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 74075a2d6d3..a3779d1ed0c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -246,6 +246,9 @@ namespace ranges
       [[no_unique_address]] __detail::__box<_Tp> _M_value;
     };
 
+  template<typename _Tp>
+    single_view(_Tp) -> single_view<_Tp>;
+
   namespace __detail
   {
     template<typename _Wp>
@@ -597,7 +600,7 @@ namespace views
     template<typename _Tp>
       constexpr auto
       operator()(_Tp&& __e) const
-      { return single_view{std::forward<_Tp>(__e)}; }
+      { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
   };
 
   inline constexpr _Single single{};
@@ -607,12 +610,12 @@ namespace views
     template<typename _Tp>
       constexpr auto
       operator()(_Tp&& __e) const
-      { return iota_view{std::forward<_Tp>(__e)}; }
+      { return iota_view(std::forward<_Tp>(__e)); }
 
     template<typename _Tp, typename _Up>
       constexpr auto
       operator()(_Tp&& __e, _Up&& __f) const
-      { return iota_view{std::forward<_Tp>(__e), std::forward<_Up>(__f)}; }
+      { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
   };
 
   inline constexpr _Iota iota{};
@@ -1336,7 +1339,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Pred>
        concept __can_filter_view
-         = requires { filter_view{std::declval<_Range>(), 
std::declval<_Pred>()}; };
+         = requires { filter_view(std::declval<_Range>(), 
std::declval<_Pred>()); };
     } // namespace __detail
 
     struct _Filter : __adaptor::_RangeAdaptor<_Filter>
@@ -1346,7 +1349,7 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Pred&& __p) const
        {
-         return filter_view{std::forward<_Range>(__r), 
std::forward<_Pred>(__p)};
+         return filter_view(std::forward<_Range>(__r), 
std::forward<_Pred>(__p));
        }
 
       using _RangeAdaptor<_Filter>::operator();
@@ -1717,7 +1720,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Fp>
        concept __can_transform_view
-         = requires { transform_view{std::declval<_Range>(), 
std::declval<_Fp>()}; };
+         = requires { transform_view(std::declval<_Range>(), 
std::declval<_Fp>()); };
     } // namespace __detail
 
     struct _Transform : __adaptor::_RangeAdaptor<_Transform>
@@ -1727,7 +1730,7 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Fp&& __f) const
        {
-         return transform_view{std::forward<_Range>(__r), 
std::forward<_Fp>(__f)};
+         return transform_view(std::forward<_Range>(__r), 
std::forward<_Fp>(__f));
        }
 
       using _RangeAdaptor<_Transform>::operator();
@@ -1813,11 +1816,11 @@ namespace views::__adaptor
            else
              {
                auto __sz = size();
-               return counted_iterator{ranges::begin(_M_base), __sz};
+               return counted_iterator(ranges::begin(_M_base), __sz);
              }
          }
        else
-         return counted_iterator{ranges::begin(_M_base), _M_count};
+         return counted_iterator(ranges::begin(_M_base), _M_count);
       }
 
       constexpr auto
@@ -1830,11 +1833,11 @@ namespace views::__adaptor
            else
              {
                auto __sz = size();
-               return counted_iterator{ranges::begin(_M_base), __sz};
+               return counted_iterator(ranges::begin(_M_base), __sz);
              }
          }
        else
-         return counted_iterator{ranges::begin(_M_base), _M_count};
+         return counted_iterator(ranges::begin(_M_base), _M_count);
       }
 
       constexpr auto
@@ -1897,7 +1900,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Tp>
        concept __can_take_view
-         = requires { take_view{std::declval<_Range>(), std::declval<_Tp>()}; 
};
+         = requires { take_view(std::declval<_Range>(), std::declval<_Tp>()); 
};
     } // namespace __detail
 
     struct _Take : __adaptor::_RangeAdaptor<_Take>
@@ -1907,7 +1910,7 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Tp&& __n) const
        {
-         return take_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
+         return take_view(std::forward<_Range>(__r), std::forward<_Tp>(__n));
        }
 
       using _RangeAdaptor<_Take>::operator();
@@ -2016,7 +2019,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Pred>
        concept __can_take_while_view
-         = requires { take_while_view{std::declval<_Range>(), 
std::declval<_Pred>()}; };
+         = requires { take_while_view(std::declval<_Range>(), 
std::declval<_Pred>()); };
     } // namespace __detail
 
     struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
@@ -2026,7 +2029,7 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Pred&& __p) const
        {
-         return take_while_view{std::forward<_Range>(__r), 
std::forward<_Pred>(__p)};
+         return take_while_view(std::forward<_Range>(__r), 
std::forward<_Pred>(__p));
        }
 
       using _RangeAdaptor<_TakeWhile>::operator();
@@ -2135,7 +2138,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Tp>
        concept __can_drop_view
-         = requires { drop_view{std::declval<_Range>(), std::declval<_Tp>()}; 
};
+         = requires { drop_view(std::declval<_Range>(), std::declval<_Tp>()); 
};
     } // namespace __detail
 
     struct _Drop : __adaptor::_RangeAdaptor<_Drop>
@@ -2145,7 +2148,7 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Tp&& __n) const
        {
-         return drop_view{std::forward<_Range>(__r), std::forward<_Tp>(__n)};
+         return drop_view(std::forward<_Range>(__r), std::forward<_Tp>(__n));
        }
 
       using _RangeAdaptor<_Drop>::operator();
@@ -2217,7 +2220,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Pred>
        concept __can_drop_while_view
-         = requires { drop_while_view{std::declval<_Range>(), 
std::declval<_Pred>()}; };
+         = requires { drop_while_view(std::declval<_Range>(), 
std::declval<_Pred>()); };
     } // namespace __detail
 
     struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
@@ -2227,8 +2230,8 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Pred&& __p) const
        {
-         return drop_while_view{std::forward<_Range>(__r),
-                                std::forward<_Pred>(__p)};
+         return drop_while_view(std::forward<_Range>(__r),
+                                std::forward<_Pred>(__p));
        }
 
       using _RangeAdaptor<_DropWhile>::operator();
@@ -2948,7 +2951,7 @@ namespace views::__adaptor
          && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
        constexpr
        split_view(_Range&& __r, range_value_t<_Range> __e)
-         : _M_pattern(std::move(__e)),
+         : _M_pattern(views::single(std::move(__e))),
            _M_base(views::all(std::forward<_Range>(__r)))
        { }
 
@@ -3012,7 +3015,7 @@ namespace views::__adaptor
     {
       template<typename _Range, typename _Pattern>
        concept __can_split_view
-         = requires { split_view{std::declval<_Range>(), 
std::declval<_Pattern>()}; };
+         = requires { split_view(std::declval<_Range>(), 
std::declval<_Pattern>()); };
     } // namespace __detail
 
     struct _Split : __adaptor::_RangeAdaptor<_Split>
@@ -3022,7 +3025,7 @@ namespace views::__adaptor
        constexpr auto
        operator()(_Range&& __r, _Pattern&& __f) const
        {
-         return split_view{std::forward<_Range>(__r), 
std::forward<_Pattern>(__f)};
+         return split_view(std::forward<_Range>(__r), 
std::forward<_Pattern>(__f));
        }
 
       using _RangeAdaptor<_Split>::operator();
@@ -3041,10 +3044,10 @@ namespace views::__adaptor
       operator()(_Iter __i, iter_difference_t<_Iter> __n) const
       {
        if constexpr (random_access_iterator<_Iter>)
-         return subrange{__i, __i + __n};
+         return subrange(__i, __i + __n);
        else
-         return subrange{counted_iterator{std::move(__i), __n},
-                         default_sentinel};
+         return subrange(counted_iterator(std::move(__i), __n),
+                         default_sentinel);
       }
     };
 
diff --git a/libstdc++-v3/testsuite/std/ranges/p2367.cc 
b/libstdc++-v3/testsuite/std/ranges/p2367.cc
new file mode 100644
index 00000000000..d099f623bfd
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/p2367.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2021 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 } }
+
+// Verify P2367 changes.
+
+#include <ranges>
+
+namespace ranges = std::ranges;
+namespace views = std::views;
+
+void
+test01()
+{
+  extern int (&x)[5];
+
+  // Verify changes to single_view.
+  using ranges::single_view;
+  using std::same_as;
+  same_as<single_view<int*>> auto v1 = views::single(x);
+  same_as<single_view<int>> auto v2 = views::single((const int)5);
+  same_as<single_view<single_view<int>>> auto v3 = views::single(v2);
+
+  // Verify changes to take_view.
+  auto v4 = views::take(x, 0ull);
+
+  // Verify changes to drop_view.
+  auto v5 = views::drop(x, 0ull);
+
+  // Verify changes to split_view.
+  auto v6 = views::split(x, 5u);
+}
-- 
2.31.1.362.g311531c9de

Reply via email to