On Fri, 13 Sep 2024, Patrick Palka wrote:

> On Fri, 13 Sep 2024, Patrick Palka wrote:
> 
> > On Fri, 13 Sep 2024, Jonathan Wakely wrote:
> > 
> > > On Sat, 3 Aug 2024 at 00:10, Jonathan Wakely <jwak...@redhat.com> wrote:
> > > >
> > > > On Fri, 2 Aug 2024 at 23:49, Giuseppe D'Angelo
> > > > <giuseppe.dang...@kdab.com> wrote:
> > > > >
> > > > > Hello,
> > > > >
> > > > > as usual thank you for the review. V2 is attached.
> > > > >
> > > > > On 02/08/2024 14:38, Jonathan Wakely wrote:
> > > > > > On Fri, 2 Aug 2024 at 13:17, Jonathan Wakely <jwak...@redhat.com> 
> > > > > > wrote:
> > > > > >>
> > > > > >> On Fri, 2 Aug 2024 at 11:45, Giuseppe D'Angelo wrote:
> > > > > >>>
> > > > > >>> Hello,
> > > > > >>>
> > > > > >>> The attached patch adds support for P2248R8 + P3217R0 (Enabling
> > > > > >>> list-initialization for algorithms, C++26). The big question is 
> > > > > >>> whether
> > > > > >>> this keeps the code readable enough without introducing too much
> > > > > >>> #ifdef-ery, so any feedback is appreciated.
> > > > > >>
> > > > > >> Putting the extra args on the algorithmfwd.h declarations is a nice
> > > > > >> way to avoid any clutter on the definitions. I think that is very
> > > > > >> readable.
> > > > > >> Another option would be to not touch those forward declarations, 
> > > > > >> but
> > > > > >> add new ones with the defaults:
> > > > > >>
> > > > > >> #if __glibcxx_default_template_type_for_algorithm_values
> > > > > >> // new declarations with default template args ...
> > > > > >> #endif
> > > > > >>
> > > > > >> But I think what you've done is good.
> > > > >
> > > > > I'll keep it then :)
> > > > >
> > > > > >> For ranges_algo.h I'm almost tempted to say we should just treat 
> > > > > >> this
> > > > > >> as a DR, to avoid the #ifdef-ery. Almost.
> > > > > >> Is there any reason we can't rearrange the template parameters fo
> > > > > >> C++20 and C++23 mode? I don't think users are allowed to use 
> > > > > >> explicit
> > > > > >> template argument lists for invoke e.g. 
> > > > > >> ranges::find.operator()<Iter,
> > > > > >> Proj> so it should be unobservable if we change the order for C++20
> > > > > >> (and just don't add the default args until C++26). That might 
> > > > > >> reduce
> > > > > >> the differences to just a line or two for each CPO.
> > > > >
> > > > > Indeed, users cannot rely on any specific order of the template
> > > > > arguments when calling algorithms. This is
> > > > >
> > > > > https://eel.is/c++draft/algorithms.requirements#15
> > > > >
> > > > > which has this note:
> > > > >
> > > > > "Consequently, an implementation can declare an algorithm with 
> > > > > different
> > > > > template parameters than those presented"
> > > > >
> > > > > which of course does apply here: it's why P2248 could do these changes
> > > > > to begin with. The only reason why I kept them in the original order 
> > > > > was
> > > > > a matter of caution, but sure, in the new patch I've changed them
> > > > > unconditionally and just used a macro to hide the default in pre-C++26
> > > > > modes. This should keep the code clean(er).
> > > > >
> > > > >
> > > > > > The merged wording also removes the redundant 'typename' from the
> > > > > > default arguments, but I think we might still need that for Clang
> > > > > > compat. I'm not sure when Clang fully implemented "down with
> > > > > > typename", but it was still causing issues some time last year.
> > > > >
> > > > > I hope it's fine if I keep it.
> > > >
> > > > Yes, certainly.
> > > >
> > > > This looks good to me now, thanks.
> > > >
> > > > Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
> > > >
> > > > Patrick, could you please review + test this some time next week? If
> > > > it's all fine and you're happy with it too, please push to trunk.
> > 
> > Sorry for completely missing this!
> > 
> > > 
> > > Looks like this wasn't applied. I've rebased it, but the new
> > > 23_containers/default_template_value.cc test fails.
> > > 
> > > The problem is that all the std::erase overloads for containers have this 
> > > added:
> > > 
> > >   template<typename _CharT, typename _Traits, typename _Alloc, typename 
> > > _Up
> > >        _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_CharT)>
> > > 
> > > But the definition of that macro expects an iterator, not the value type.
> > > 
> > > Was the new test actually run?
> > > 
> > > I've attached the rebased patch, which needs fixes for the std::erase 
> > > overloads.
> > > 
> > 
> > > commit 3098548ec2349339044d95a7e17d144913b493de
> > > Author: Jonathan Wakely <jwak...@redhat.com>
> > > Date:   Fri Sep 13 10:18:46 2024
> > > 
> > >     libstdc++: add default template parameters to algorithms
> > >     
> > >     This implements P2248R8 + P3217R0, both approved for C++26.
> > >     The changes are mostly mechanical; the struggle is to keep readability
> > >     with the pre-P2248 signatures.
> > >     
> > >     * For containers, "classic STL" algorithms and their parallel 
> > > versions,
> > >       introduce a macro and amend their declarations/definitions with it.
> > >       The macro either expands to the defaulted parameter or to nothing
> > >       in pre-C++26 modes.
> > >     
> > >     * For range algorithms, we need to reorder their template parameters.
> > >       I've done so unconditionally, because users cannot rely on template
> > >       parameters of algorithms (this is explicitly authorized by
> > >       [algorithms.requirements]/15). The defaults are then hidden behind
> > >       another macro.
> > >     
> > >     libstdc++-v3/ChangeLog:
> > >     
> > >             * include/bits/iterator_concepts.h: Add projected_value_t.
> > >             * include/bits/algorithmfwd.h: Add the default template
> > >             parameter to the relevant forward declarations.
> > >             * include/pstl/glue_algorithm_defs.h: Likewise.
> > >             * include/bits/ranges_algo.h: Add the default template
> > >             parameter to range-based algorithms.
> > >             * include/bits/ranges_algobase.h: Likewise.
> > >             * include/bits/ranges_util.h: Likewise.
> > >             * include/bits/ranges_base.h: Add helper macros.
> > >             * include/bits/stl_iterator_base_types.h: Add helper macro.
> > >             * include/bits/version.def: Add the new feature-testing macro.
> > >             * include/bits/version.h: Regenerate.
> > >             * include/std/algorithm: Pull the feature-testing macro.
> > >             * include/std/ranges: Likewise.
> > >             * include/std/deque: Pull the feature-testing macro, add
> > >             the default for std::erase.
> > >             * include/std/forward_list: Likewise.
> > >             * include/std/list: Likewise.
> > >             * include/std/string: Likewise.
> > >             * include/std/vector: Likewise.
> > >             * testsuite/23_containers/default_template_value.cc: New test.
> > >             * testsuite/25_algorithms/default_template_value.cc: New test.
> > >     
> > >     Signed-off-by: Giuseppe D'Angelo <giuseppe.dang...@kdab.com>
> > > 
> > > diff --git a/libstdc++-v3/include/bits/algorithmfwd.h 
> > > b/libstdc++-v3/include/bits/algorithmfwd.h
> > > index 34bf9921f43..88fac34e72f 100644
> > > --- a/libstdc++-v3/include/bits/algorithmfwd.h
> > > +++ b/libstdc++-v3/include/bits/algorithmfwd.h
> > > @@ -203,12 +203,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >      any_of(_IIter, _IIter, _Predicate);
> > >  #endif
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      bool
> > >      binary_search(_FIter, _FIter, const _Tp&);
> > >  
> > > -  template<typename _FIter, typename _Tp, typename _Compare>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter),
> > > +    typename _Compare>
> > >      _GLIBCXX20_CONSTEXPR
> > >      bool
> > >      binary_search(_FIter, _FIter, const _Tp&, _Compare);
> > > @@ -250,22 +253,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >    // count
> > >    // count_if
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      pair<_FIter, _FIter>
> > >      equal_range(_FIter, _FIter, const _Tp&);
> > >  
> > > -  template<typename _FIter, typename _Tp, typename _Compare>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter),
> > > +    typename _Compare>
> > >      _GLIBCXX20_CONSTEXPR
> > >      pair<_FIter, _FIter>
> > >      equal_range(_FIter, _FIter, const _Tp&, _Compare);
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      void
> > >      fill(_FIter, _FIter, const _Tp&);
> > >  
> > > -  template<typename _OIter, typename _Size, typename _Tp>
> > > +  template<typename _OIter, typename _Size, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_OIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _OIter
> > >      fill_n(_OIter, _Size, const _Tp&);
> > > @@ -377,12 +385,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >      void
> > >      iter_swap(_FIter1, _FIter2);
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > >      lower_bound(_FIter, _FIter, const _Tp&);
> > >  
> > > -  template<typename _FIter, typename _Tp, typename _Compare>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter),
> > > +    typename _Compare>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > >      lower_bound(_FIter, _FIter, const _Tp&, _Compare);
> > > @@ -553,7 +564,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >  
> > >    // random_shuffle
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > >      remove(_FIter, _FIter, const _Tp&);
> > > @@ -563,7 +575,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >      _FIter
> > >      remove_if(_FIter, _FIter, _Predicate);
> > >  
> > > -  template<typename _IIter, typename _OIter, typename _Tp>
> > > +  template<typename _IIter, typename _OIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_IIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _OIter
> > >      remove_copy(_IIter, _IIter, _OIter, const _Tp&);
> > > @@ -580,7 +593,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >      _OIter
> > >      replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
> > >  
> > > -  template<typename _Iter, typename _OIter, typename _Predicate, 
> > > typename _Tp>
> > > +  template<typename _Iter, typename _OIter, typename _Predicate, 
> > > typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_OIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _OIter
> > >      replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
> > > @@ -673,12 +687,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> > >  
> > >    // unique_copy
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > >      upper_bound(_FIter, _FIter, const _Tp&);
> > >  
> > > -  template<typename _FIter, typename _Tp, typename _Compare>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter),
> > > +    typename _Compare>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > >      upper_bound(_FIter, _FIter, const _Tp&, _Compare);
> > > @@ -695,7 +712,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
> > >      _FIter
> > >      adjacent_find(_FIter, _FIter, _BinaryPredicate);
> > >  
> > > -  template<typename _IIter, typename _Tp>
> > > +  template<typename _IIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_IIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      typename iterator_traits<_IIter>::difference_type
> > >      count(_IIter, _IIter, const _Tp&);
> > > @@ -715,7 +733,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
> > >      bool
> > >      equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
> > >  
> > > -  template<typename _IIter, typename _Tp>
> > > +  template<typename _IIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_IIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _IIter
> > >      find(_IIter, _IIter, const _Tp&);
> > > @@ -843,12 +862,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
> > >  #endif
> > >  #endif // HOSTED
> > >  
> > > -  template<typename _FIter, typename _Tp>
> > > +  template<typename _FIter, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      void
> > >      replace(_FIter, _FIter, const _Tp&, const _Tp&);
> > >  
> > > -  template<typename _FIter, typename _Predicate, typename _Tp>
> > > +  template<typename _FIter, typename _Predicate, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      void
> > >      replace_if(_FIter, _FIter, _Predicate, const _Tp&);
> > > @@ -863,12 +884,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
> > >      _FIter1
> > >      search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
> > >  
> > > -  template<typename _FIter, typename _Size, typename _Tp>
> > > +  template<typename _FIter, typename _Size, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter)>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > >      search_n(_FIter, _FIter, _Size, const _Tp&);
> > >  
> > > -  template<typename _FIter, typename _Size, typename _Tp,
> > > +  template<typename _FIter, typename _Size, typename _Tp
> > > +    _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_FIter),
> > >      typename _BinaryPredicate>
> > >      _GLIBCXX20_CONSTEXPR
> > >      _FIter
> > > diff --git a/libstdc++-v3/include/bits/iterator_concepts.h 
> > > b/libstdc++-v3/include/bits/iterator_concepts.h
> > > index 642c709fee0..91ee6a4c6de 100644
> > > --- a/libstdc++-v3/include/bits/iterator_concepts.h
> > > +++ b/libstdc++-v3/include/bits/iterator_concepts.h
> > > @@ -826,6 +826,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >        using type = invoke_result_t<_Proj&, __indirect_value_t<_Iter>>;
> > >      };
> > >  
> > > +#if __glibcxx_algorithm_default_value_type // C++ >= 26
> > > +  template<indirectly_readable _Iter,
> > > +    indirectly_regular_unary_invocable<_Iter> _Proj>
> > > +    using projected_value_t
> > > + = remove_cvref_t<invoke_result_t<_Proj&, iter_value_t<_Iter>&>>;
> 
> Ah, we very recently implemented P2609R3 which has the following note
> about projected_value_t: https://wg21.link/p2609r3#proposal
> 
> Do we want to honor this note here and define projected_value_t as
> remove_cvref_t<__indirect_value_t<_Iter>> then?  It seems the working
> draft doesn't define it that way despite having merged both these
> papers.

Oops, that seems wrong, it seems the correct definition in terms
of indirect_value_t should be

  remove_cvref_t<indirect_value_t<projected<I, Proj>>>

as mentioned in P2248R8/5.9.1.

> 
> 
> > > +#endif + // [alg.req], common algorithm requirements
> > >  
> > >    /// [alg.req.ind.move], concept `indirectly_movable` diff --git
> > >    a/libstdc++-v3/include/bits/ranges_algo.h
> > >    b/libstdc++-v3/include/bits/ranges_algo.h index
> > >    d258be0b93f..9a117ae1ff1 100644 ---
> > >    a/libstdc++-v3/include/bits/ranges_algo.h +++
> > >    b/libstdc++-v3/include/bits/ranges_algo.h @@ -281,7 +281,9 @@
> > >    namespace ranges struct __count_fn { template<input_iterator
> > >    _Iter, sentinel_for<_Iter> _Sent, -         typename _Tp,
> > >    typename _Proj = identity> +        typename _Proj = identity,
> > >    +           typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >    _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > >    projected<_Iter, _Proj>, const _Tp*> @@ -296,7 +298,9 @@
> > >    namespace ranges return __n; }
> > >  
> > > -    template<input_range _Range, typename _Tp, typename _Proj =
> > > identity> +    template<input_range _Range, typename _Proj =
> > > identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, const _Tp*> @@ -344,8
> > > +348,10 @@ namespace ranges
> > >  
> > >    struct __search_n_fn { -    template<forward_iterator _Iter,
> > >    sentinel_for<_Iter> _Sent, typename _Tp, -          typename
> > >    _Pred = ranges::equal_to, typename _Proj = identity> +
> > >    template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, +
> > >    typename _Pred = ranges::equal_to, typename _Proj = identity, +
> > >    typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >    _Proj)> requires indirectly_comparable<_Iter, const _Tp*,
> > >    _Pred, _Proj> constexpr subrange<_Iter> operator()(_Iter
> > >    __first, _Sent __last, iter_difference_t<_Iter> __count, @@
> > >    -416,8 +422,10 @@ namespace ranges } }
> > >  
> > > -    template<forward_range _Range, typename _Tp, -
> > > typename _Pred = ranges::equal_to, typename _Proj = identity> +
> > > template<forward_range _Range, +       typename _Pred =
> > > ranges::equal_to, typename _Proj = identity, +         typename
> > > _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj)> requires indirectly_comparable<iterator_t<_Range>, const
> > > _Tp*, _Pred, _Proj> constexpr borrowed_subrange_t<_Range> @@
> > > -774,7 +782,11 @@ namespace ranges struct __replace_fn {
> > > template<input_iterator _Iter, sentinel_for<_Iter> _Sent, -
> > > typename _Tp1, typename _Tp2, typename _Proj = identity> +
> > > typename _Proj = identity, +           typename _Tp1 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj),
> > > +      typename _Tp2 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(_Tp1)> requires
> > > indirectly_writable<_Iter, const _Tp2&> &&
> > > indirect_binary_predicate<ranges::equal_to, projected<_Iter,
> > > _Proj>, const _Tp1*> @@ -789,8 +801,11 @@ namespace ranges return
> > > __first; }
> > >  
> > > -    template<input_range _Range, -            typename _Tp1,
> > > typename _Tp2, typename _Proj = identity> +
> > > template<input_range _Range, typename _Proj = identity, +
> > > typename _Tp1 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj), +      typename _Tp2 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(_Tp1)> requires
> > > indirectly_writable<iterator_t<_Range>, const _Tp2&> &&
> > > indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, @@ -810,7 +825,9 @@
> > > namespace ranges struct __replace_if_fn { template<input_iterator
> > > _Iter, sentinel_for<_Iter> _Sent, -            typename _Tp,
> > > typename _Proj = identity, +           typename _Proj = identity,
> > > +      typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj),
> > > indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> requires
> > > indirectly_writable<_Iter, const _Tp&> constexpr _Iter @@ -823,7
> > > +840,9 @@ namespace ranges return std::move(__first); }
> > >  
> > > -    template<input_range _Range, typename _Tp, typename _Proj =
> > > identity, +    template<input_range _Range, typename _Proj =
> > > identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj), indirect_unary_predicate<projected<iterator_t<_Range>,
> > > _Proj>> _Pred> requires indirectly_writable<iterator_t<_Range>,
> > > const _Tp&> @@ -844,11 +863,15 @@ namespace ranges struct
> > > __replace_copy_fn { template<input_iterator _Iter,
> > > sentinel_for<_Iter> _Sent, -           typename _Tp1, typename
> > > _Tp2, output_iterator<const _Tp2&> _Out, -             typename
> > > _Proj = identity> +            typename _Out, typename _Proj =
> > > identity, +            typename _Tp1 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj),
> > > +      typename _Tp2 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Out>)>
> > > requires indirectly_copyable<_Iter, _Out> &&
> > > indirect_binary_predicate<ranges::equal_to, projected<_Iter,
> > > _Proj>, const _Tp1*> +    && output_iterator<_Out, const _Tp2&>
> > > constexpr replace_copy_result<_Iter, _Out> operator()(_Iter
> > > __first, _Sent __last, _Out __result, const _Tp1& __old_value,
> > > const _Tp2& __new_value, @@ -862,12 +885,17 @@ namespace ranges
> > > return {std::move(__first), std::move(__result)}; }
> > >  
> > > -    template<input_range _Range, typename _Tp1, typename _Tp2, -
> > > output_iterator<const _Tp2&> _Out, typename _Proj = identity> +
> > > template<input_range _Range, typename _Out, +          typename
> > > _Proj = identity, +            typename _Tp1 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj), +      typename _Tp2 +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Out>)>
> > > requires indirectly_copyable<iterator_t<_Range>, _Out> &&
> > > indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, const _Tp1*> +      &&
> > > output_iterator<_Out, const _Tp2&> constexpr
> > > replace_copy_result<borrowed_iterator_t<_Range>, _Out>
> > > operator()(_Range&& __r, _Out __result, const _Tp1& __old_value,
> > > const _Tp2& __new_value, @@ -887,10 +915,13 @@ namespace ranges
> > > struct __replace_copy_if_fn { template<input_iterator _Iter,
> > > sentinel_for<_Iter> _Sent, -           typename _Tp,
> > > output_iterator<const _Tp&> _Out, +            typename _Out, +
> > > typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Out>),
> > > typename _Proj = identity,
> > > indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> requires
> > > indirectly_copyable<_Iter, _Out> +        && output_iterator<_Out,
> > > const _Tp&> constexpr replace_copy_if_result<_Iter, _Out>
> > > operator()(_Iter __first, _Sent __last, _Out __result, _Pred
> > > __pred, const _Tp& __new_value, _Proj __proj = {}) const @@
> > > -904,11 +935,14 @@ namespace ranges }
> > >  
> > >      template<input_range _Range, -            typename _Tp,
> > >      output_iterator<const _Tp&> _Out, +       typename _Out, +
> > >      typename _Tp +
> > >      _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Out>),
> > >      typename _Proj = identity,
> > >      indirect_unary_predicate<projected<iterator_t<_Range>,
> > >      _Proj>> _Pred> requires
> > >      indirectly_copyable<iterator_t<_Range>, _Out> +      &&
> > >      output_iterator<_Out, const _Tp&> constexpr
> > >      replace_copy_if_result<borrowed_iterator_t<_Range>, _Out>
> > >      operator()(_Range&& __r, _Out __result, _Pred __pred, const
> > >      _Tp& __new_value, _Proj __proj = {}) const @@ -1004,7 +1038,9
> > >      @@ namespace ranges struct __remove_fn { template<permutable
> > >      _Iter, sentinel_for<_Iter> _Sent, -       typename _Tp,
> > >      typename _Proj = identity> +      typename _Proj = identity,
> > >      +         typename _Tp +
> > >      _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >      _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > >      projected<_Iter, _Proj>, const _Tp*> @@ -1019,7 +1055,9 @@
> > >      namespace ranges std::move(__pred), std::move(__proj)); }
> > >  
> > > -    template<forward_range _Range, typename _Tp, typename _Proj =
> > > identity> +    template<forward_range _Range, typename _Proj =
> > > identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj)> requires permutable<iterator_t<_Range>> &&
> > > indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, @@ -1079,7 +1117,9 @@
> > > namespace ranges struct __remove_copy_fn { template<input_iterator
> > > _Iter, sentinel_for<_Iter> _Sent, -
> > > weakly_incrementable _Out, typename _Tp, typename _Proj =
> > > identity> +            weakly_incrementable _Out, typename _Proj =
> > > identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj)>
> > > requires indirectly_copyable<_Iter, _Out> &&
> > > indirect_binary_predicate<ranges::equal_to, projected<_Iter,
> > > _Proj>, @@ -1098,7 +1138,9 @@ namespace ranges }
> > >  
> > >      template<input_range _Range, weakly_incrementable _Out, -
> > >      typename _Tp, typename _Proj = identity> +        typename
> > >      _Proj = identity, +       typename _Tp +
> > >      
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > >      _Proj)> requires indirectly_copyable<iterator_t<_Range>,
> > >      _Out> && indirect_binary_predicate<ranges::equal_to,
> > >      projected<iterator_t<_Range>, _Proj>, @@ -2047,7 +2089,9 @@
> > >      namespace ranges struct __lower_bound_fn {
> > >      template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, -
> > >      typename _Tp, typename _Proj = identity, +        typename
> > >      _Proj = identity, +       typename _Tp +
> > >      _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >      _Proj), indirect_strict_weak_order<const _Tp*,
> > >      projected<_Iter, _Proj>> _Comp = ranges::less> constexpr
> > >      _Iter @@ -2073,7 +2117,10 @@ namespace ranges return __first;
> > >      }
> > >  
> > > -    template<forward_range _Range, typename _Tp, typename _Proj =
> > > identity, +    template<forward_range _Range, +        typename
> > > _Proj = identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj), indirect_strict_weak_order<const _Tp*,
> > > projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> @@
> > > -2091,7 +2138,9 @@ namespace ranges struct __upper_bound_fn {
> > > template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, -
> > > typename _Tp, typename _Proj = identity, +             typename
> > > _Proj = identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj),
> > > indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
> > > _Comp = ranges::less> constexpr _Iter @@ -2117,7 +2166,10 @@
> > > namespace ranges return __first; }
> > >  
> > > -    template<forward_range _Range, typename _Tp, typename _Proj =
> > > identity, +    template<forward_range _Range, +        typename
> > > _Proj = identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj), indirect_strict_weak_order<const _Tp*,
> > > projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> @@
> > > -2135,7 +2187,9 @@ namespace ranges struct __equal_range_fn {
> > > template<forward_iterator _Iter, sentinel_for<_Iter> _Sent, -
> > > typename _Tp, typename _Proj = identity, +             typename
> > > _Proj = identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj),
> > > indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>>
> > > _Comp = ranges::less> constexpr subrange<_Iter> @@ -2177,7 +2231,9
> > > @@ namespace ranges }
> > >  
> > >      template<forward_range _Range, -          typename _Tp,
> > >      typename _Proj = identity, +      typename _Proj = identity,
> > >      +         typename _Tp +
> > >      
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > >      _Proj), indirect_strict_weak_order<const _Tp*,
> > >      projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
> > >      @@ -2195,7 +2251,9 @@ namespace ranges struct
> > >      __binary_search_fn { template<forward_iterator _Iter,
> > >      sentinel_for<_Iter> _Sent, -      typename _Tp, typename
> > >      _Proj = identity, +       typename _Proj = identity, +
> > >      typename _Tp +
> > >      _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >      _Proj), indirect_strict_weak_order<const _Tp*,
> > >      projected<_Iter, _Proj>> _Comp = ranges::less> constexpr bool
> > >      @@ -2210,7 +2268,9 @@ namespace ranges }
> > >  
> > >      template<forward_range _Range, -          typename _Tp,
> > >      typename _Proj = identity, +      typename _Proj = identity,
> > >      +         typename _Tp +
> > >      
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > >      _Proj), indirect_strict_weak_order<const _Tp*,
> > >      projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
> > >      @@ -3469,14 +3529,19 @@ namespace ranges struct __contains_fn
> > >      { template<input_iterator _Iter, sentinel_for<_Iter> _Sent, -
> > >      typename _Tp, typename _Proj = identity> +       typename
> > >      _Proj = identity, +      typename _Tp +
> > >      _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >      _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > >      projected<_Iter, _Proj>, const _Tp*> constexpr bool
> > >      operator()(_Iter __first, _Sent __last, const _Tp& __value,
> > >      _Proj __proj = {}) const { return
> > >      ranges::find(std::move(__first), __last, __value,
> > >      std::move(__proj)) != __last; }
> > >  
> > > -    template<input_range _Range, typename _Tp, typename _Proj =
> > > identity> +    template<input_range _Range, +         typename
> > > _Proj = identity, +           typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, const _Tp*> constexpr bool
> > > @@ -3525,7 +3590,10 @@ namespace ranges
> > >  
> > >    struct __find_last_fn { -    template<forward_iterator _Iter,
> > >    sentinel_for<_Iter> _Sent, typename _Tp, typename _Proj =
> > >    identity> +    template<forward_iterator _Iter,
> > >    sentinel_for<_Iter> _Sent, +        typename _Proj = identity,
> > >    +           typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter,
> > >    _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > >    projected<_Iter, _Proj>, const _Tp*> constexpr subrange<_Iter>
> > >    operator()(_Iter __first, _Sent __last, const _Tp& __value,
> > >    _Proj __proj = {}) const @@ -3556,7 +3624,9 @@ namespace ranges
> > >    } }
> > >  
> > > -    template<forward_range _Range, typename _Tp, typename _Proj =
> > > identity> +    template<forward_range _Range, typename _Proj =
> > > identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, const _Tp*> constexpr
> > > borrowed_subrange_t<_Range> operator()(_Range&& __r, const _Tp&
> > > __value, _Proj __proj = {}) const @@ -3730,7 +3800,8 @@ namespace
> > > ranges return _Ret{std::move(__first), std::move(__accum)}; }
> > >  
> > > -    template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
> > > typename _Tp, +    template<input_iterator _Iter,
> > > sentinel_for<_Iter> _Sent, typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Iter>),
> > > __detail::__indirectly_binary_left_foldable<_Tp, _Iter> _Fp>
> > > constexpr auto operator()(_Iter __first, _Sent __last, _Tp __init,
> > > _Fp __f) const @@ -3740,7 +3811,8 @@ namespace ranges
> > > std::move(__init), std::move(__f)); }
> > >  
> > > -    template<input_range _Range, typename _Tp, +
> > > template<input_range _Range, typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(range_value_t<_Range>),
> > > __detail::__indirectly_binary_left_foldable<_Tp,
> > > iterator_t<_Range>> _Fp> constexpr auto operator()(_Range&& __r,
> > > _Tp __init, _Fp __f) const @@ -3755,7 +3827,8 @@ namespace ranges
> > >  
> > >    struct __fold_left_fn { -    template<input_iterator _Iter,
> > >    sentinel_for<_Iter> _Sent, typename _Tp, +
> > >    template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
> > >    typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Iter>),
> > >    __detail::__indirectly_binary_left_foldable<_Tp, _Iter> _Fp>
> > >    constexpr auto operator()(_Iter __first, _Sent __last, _Tp
> > >    __init, _Fp __f) const @@ -3764,7 +3837,8 @@ namespace ranges
> > >    std::move(__init), std::move(__f)).value; }
> > >  
> > > -    template<input_range _Range, typename _Tp, +
> > > template<input_range _Range, typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(range_value_t<_Range>),
> > > __detail::__indirectly_binary_left_foldable<_Tp,
> > > iterator_t<_Range>> _Fp> constexpr auto operator()(_Range&& __r,
> > > _Tp __init, _Fp __f) const @@ -3842,7 +3916,8 @@ namespace ranges
> > >  
> > >    struct __fold_right_fn { -    template<bidirectional_iterator
> > >    _Iter, sentinel_for<_Iter> _Sent, typename _Tp, +
> > >    template<bidirectional_iterator _Iter, sentinel_for<_Iter>
> > >    _Sent, typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Iter>),
> > >    __detail::__indirectly_binary_right_foldable<_Tp, _Iter> _Fp>
> > >    constexpr auto operator()(_Iter __first, _Sent __last, _Tp
> > >    __init, _Fp __f) const @@ -3859,7 +3934,8 @@ namespace ranges
> > >    return __accum; }
> > >  
> > > -    template<bidirectional_range _Range, typename _Tp, +
> > > template<bidirectional_range _Range, typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(range_value_t<_Range>),
> > > __detail::__indirectly_binary_right_foldable<_Tp,
> > > iterator_t<_Range>> _Fp> constexpr auto operator()(_Range&& __r,
> > > _Tp __init, _Fp __f) const diff --git
> > > a/libstdc++-v3/include/bits/ranges_algobase.h
> > > b/libstdc++-v3/include/bits/ranges_algobase.h index
> > > fd35b8ba14c..39cf06bdd3e 100644 ---
> > > a/libstdc++-v3/include/bits/ranges_algobase.h +++
> > > b/libstdc++-v3/include/bits/ranges_algobase.h @@ -536,7 +536,9 @@
> > > namespace ranges
> > >  
> > >    struct __fill_n_fn { -    template<typename _Tp,
> > >    output_iterator<const _Tp&> _Out> +    template<typename _Out,
> > >    typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Out>)>
> > >    +      requires output_iterator<_Out, const _Tp&> constexpr
> > >    _Out operator()(_Out __first, iter_difference_t<_Out> __n,
> > >    const _Tp& __value) const @@ -581,8 +583,11 @@ namespace ranges
> > >  
> > >    struct __fill_fn { -    template<typename _Tp, -
> > >    output_iterator<const _Tp&> _Out, sentinel_for<_Out> _Sent> +
> > >    template<typename _Out, +           sentinel_for<_Out> _Sent, +
> > >    typename _Tp +
> > >    _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(iter_value_t<_Out>)>
> > >    +      requires output_iterator<_Out, const _Tp&> constexpr
> > >    _Out operator()(_Out __first, _Sent __last, const _Tp& __value)
> > >    const { @@ -608,7 +613,10 @@ namespace ranges } }
> > >  
> > > -    template<typename _Tp, output_range<const _Tp&> _Range> +
> > > template<typename _Range, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(range_value_t<_Range>)>
> > > +      requires output_range<_Range, const _Tp&> constexpr
> > > borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Tp&
> > > __value) const { diff --git
> > > a/libstdc++-v3/include/bits/ranges_base.h
> > > b/libstdc++-v3/include/bits/ranges_base.h index
> > > 63eb552b48b..1a26df4c4c3 100644 ---
> > > a/libstdc++-v3/include/bits/ranges_base.h +++
> > > b/libstdc++-v3/include/bits/ranges_base.h @@ -39,6 +39,15 @@
> > > #include <bits/max_size_type.h> #include <bits/version.h>
> > >  
> > > +#if __glibcxx_algorithm_default_value_type // C++ >= 26 +# define
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(_X) = _X +# define
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_I, _P) \ +
> > > = projected_value_t<_I, _P> +#else +# define
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE(_X) +# define
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_I, _P) +#endif
> > > + #ifdef __cpp_lib_concepts namespace std
> > > _GLIBCXX_VISIBILITY(default) { diff --git
> > > a/libstdc++-v3/include/bits/ranges_util.h
> > > b/libstdc++-v3/include/bits/ranges_util.h index
> > > e6d96073e87..139c272046f 100644 ---
> > > a/libstdc++-v3/include/bits/ranges_util.h +++
> > > b/libstdc++-v3/include/bits/ranges_util.h @@ -487,8 +487,10 @@
> > > namespace ranges { struct __find_fn { -    template<input_iterator
> > > _Iter, sentinel_for<_Iter> _Sent, typename _Tp, -      typename
> > > _Proj = identity> +    template<input_iterator _Iter,
> > > sentinel_for<_Iter> _Sent, +           typename _Proj = identity,
> > > +      typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(_Iter, _Proj)>
> > > requires indirect_binary_predicate<ranges::equal_to,
> > > projected<_Iter, _Proj>, const _Tp*> constexpr _Iter @@ -521,7
> > > +523,9 @@ namespace ranges return __first; }
> > >  
> > > -    template<input_range _Range, typename _Tp, typename _Proj =
> > > identity> +    template<input_range _Range, typename _Proj =
> > > identity, +            typename _Tp +
> > > _GLIBCXX26_RANGE_ALGORITHM_DEFAULT_VALUE_TYPE_PROJ(iterator_t<_Range>,
> > > _Proj)> requires indirect_binary_predicate<ranges::equal_to,
> > > projected<iterator_t<_Range>, _Proj>, const _Tp*> diff --git
> > > a/libstdc++-v3/include/bits/stl_iterator_base_types.h
> > > b/libstdc++-v3/include/bits/stl_iterator_base_types.h index
> > > 07beec3554d..2b87324eb77 100644 ---
> > > a/libstdc++-v3/include/bits/stl_iterator_base_types.h +++
> > > b/libstdc++-v3/include/bits/stl_iterator_base_types.h @@ -269,4
> > > +269,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > > _GLIBCXX_END_NAMESPACE_VERSION } // namespace
> > >  
> > > +#if __glibcxx_algorithm_default_value_type // C++ >= 26 +# define
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_Iterator) \ +     =
> > > typename iterator_traits<_Iterator>::value_type +#else +# define
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_It)
> > 
> > Small nit, but these should consistently use _Iterator or _It as the
> > parameter name in both branches.
> > 
> > Maybe we should abbreviate these macro names to
> > _GLIBCXX26_ALGO_DEF_VAL_T etc so that we can fit most uses on the
> > same line as the template parameter declaration (without exceeding
> > line length limits)?  Either way this patch + your followup LGTM.
> > 
> > > +#endif + #endif /* _STL_ITERATOR_BASE_TYPES_H */ diff --git
> > > a/libstdc++-v3/include/bits/version.def
> > > b/libstdc++-v3/include/bits/version.def index
> > > bd3af9cba99..0475c8d002a 100644 ---
> > > a/libstdc++-v3/include/bits/version.def +++
> > > b/libstdc++-v3/include/bits/version.def @@ -1782,6 +1782,14 @@
> > > ftms = { }; };
> > >  
> > > +ftms = { +  name = algorithm_default_value_type; +  values = { +
> > > v = 202403; +    cxxmin = 26; +  }; +}; + ftms = { name =
> > > fstream_native_handle; values = { diff --git
> > > a/libstdc++-v3/include/bits/version.h
> > > b/libstdc++-v3/include/bits/version.h index
> > > 364e3a05f0e..73050a1ea35 100644 ---
> > > a/libstdc++-v3/include/bits/version.h +++
> > > b/libstdc++-v3/include/bits/version.h @@ -1968,6 +1968,16 @@
> > > #endif /* !defined(__cpp_lib_unreachable) &&
> > > defined(__glibcxx_want_unreachable) */ #undef
> > > __glibcxx_want_unreachable
> > >  
> > > +#if !defined(__cpp_lib_algorithm_default_value_type) +# if
> > > (__cplusplus >  202302L) +#  define
> > > __glibcxx_algorithm_default_value_type 202403L +#  if
> > > defined(__glibcxx_want_all) ||
> > > defined(__glibcxx_want_algorithm_default_value_type) +#   define
> > > __cpp_lib_algorithm_default_value_type 202403L +#  endif +# endif
> > > +#endif /* !defined(__cpp_lib_algorithm_default_value_type) &&
> > > defined(__glibcxx_want_algorithm_default_value_type) */ +#undef
> > > __glibcxx_want_algorithm_default_value_type + #if
> > > !defined(__cpp_lib_fstream_native_handle) # if (__cplusplus >
> > > 202302L) && _GLIBCXX_HOSTED #  define
> > > __glibcxx_fstream_native_handle 202306L diff --git
> > > a/libstdc++-v3/include/pstl/glue_algorithm_defs.h
> > > b/libstdc++-v3/include/pstl/glue_algorithm_defs.h index
> > > cef78e22e31..cf997b5f3bc 100644 ---
> > > a/libstdc++-v3/include/pstl/glue_algorithm_defs.h +++
> > > b/libstdc++-v3/include/pstl/glue_algorithm_defs.h @@ -10,6 +10,7
> > > @@ #ifndef _PSTL_GLUE_ALGORITHM_DEFS_H #define
> > > _PSTL_GLUE_ALGORITHM_DEFS_H
> > >  
> > > +#include <bits/stl_iterator_base_types.h> #include
> > > <bits/stl_pair.h>
> > >  
> > >  #include "execution_defs.h" @@ -55,7 +56,7 @@ template <class
> > >  _ExecutionPolicy, class _ForwardIterator, class _Predicate>
> > >  __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > >  _ForwardIterator> find_if_not(_ExecutionPolicy&& __exec,
> > >  _ForwardIterator __first, _ForwardIterator __last, _Predicate
> > >  __pred);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Tp> +template <class _ExecutionPolicy, class _ForwardIterator,
> > > class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator> find(_ExecutionPolicy&& __exec, _ForwardIterator
> > > __first, _ForwardIterator __last, const _Tp& __value);
> > >  
> > > @@ -95,7 +96,7 @@ adjacent_find(_ExecutionPolicy&& __exec,
> > > _ForwardIterator __first, _ForwardItera
> > >  
> > >  // [alg.count]
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Tp> +template <class _ExecutionPolicy, class _ForwardIterator,
> > > class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > typename iterator_traits<_ForwardIterator>::difference_type>
> > > count(_ExecutionPolicy&& __exec, _ForwardIterator __first,
> > > _ForwardIterator __last, const _Tp& __value); @@ -117,12 +118,12
> > > @@
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardItera search(_ExecutionPolicy&& __exec, _ForwardIterator1
> > > __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
> > > _ForwardIterator2 __s_last);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Size, class _Tp, class _BinaryPredicate> +template <class
> > > _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator), class
> > > _BinaryPredicate>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator> search_n(_ExecutionPolicy&& __exec,
> > > _ForwardIterator __first, _ForwardIterator __last, _Size __count,
> > > const _Tp& __value, _BinaryPredicate __pred);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Size, class _Tp> +template <class _ExecutionPolicy, class
> > > _ForwardIterator, class _Size, class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator> search_n(_ExecutionPolicy&& __exec,
> > > _ForwardIterator __first, _ForwardIterator __last, _Size __count,
> > > const _Tp& __value); @@ -164,17 +165,17 @@
> > > transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1,
> > > _ForwardIterato
> > >  
> > >  // [alg.replace]
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _UnaryPredicate, class _Tp> +template <class _ExecutionPolicy,
> > > class _ForwardIterator, class _UnaryPredicate, class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > void> replace_if(_ExecutionPolicy&& __exec, _ForwardIterator
> > > __first, _ForwardIterator __last, _UnaryPredicate __pred, const
> > > _Tp& __new_value);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Tp> +template <class _ExecutionPolicy, class _ForwardIterator,
> > > class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > void> replace(_ExecutionPolicy&& __exec, _ForwardIterator __first,
> > > _ForwardIterator __last, const _Tp& __old_value, const _Tp&
> > > __new_value);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator1, class
> > > _ForwardIterator2, class _UnaryPredicate, class _Tp> +template
> > > <class _ExecutionPolicy, class _ForwardIterator1, class
> > > _ForwardIterator2, class _UnaryPredicate, class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator2)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator2> replace_copy_if(_ExecutionPolicy&& __exec,
> > > _ForwardIterator1 __first, _ForwardIterator1 __last,
> > > _ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp&
> > > __new_value); @@ -186,11 +187,11 @@
> > > replace_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first,
> > > _ForwardItera
> > >  
> > >  // [alg.fill]
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Tp> +template <class _ExecutionPolicy, class _ForwardIterator,
> > > class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > void> fill(_ExecutionPolicy&& __exec, _ForwardIterator __first,
> > > _ForwardIterator __last, const _Tp& __value);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Size, class _Tp> +template <class _ExecutionPolicy, class
> > > _ForwardIterator, class _Size, class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator> fill_n(_ExecutionPolicy&& __exec,
> > > _ForwardIterator __first, _Size __count, const _Tp& __value);
> > >  
> > > @@ -210,7 +211,7 @@
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardItera remove_copy_if(_ExecutionPolicy&& __exec,
> > > _ForwardIterator1 __first, _ForwardIterator1 __last,
> > > _ForwardIterator2 __result, _Predicate __pred);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator1, class
> > > _ForwardIterator2, class _Tp> +template <class _ExecutionPolicy,
> > > class _ForwardIterator1, class _ForwardIterator2, class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator1)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator2> remove_copy(_ExecutionPolicy&& __exec,
> > > _ForwardIterator1 __first, _ForwardIterator1 __last,
> > > _ForwardIterator2 __result, const _Tp& __value); @@ -219,7 +220,7
> > > @@ template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _UnaryPredicate>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator> remove_if(_ExecutionPolicy&& __exec,
> > > _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate
> > > __pred);
> > >  
> > > -template <class _ExecutionPolicy, class _ForwardIterator, class
> > > _Tp> +template <class _ExecutionPolicy, class _ForwardIterator,
> > > class _Tp
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_ForwardIterator)>
> > > __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
> > > _ForwardIterator> remove(_ExecutionPolicy&& __exec,
> > > _ForwardIterator __first, _ForwardIterator __last, const _Tp&
> > > __value);
> > >  
> > > diff --git a/libstdc++-v3/include/std/algorithm
> > > b/libstdc++-v3/include/std/algorithm index
> > > 163e6b5dca7..b410e7c281b 100644 ---
> > > a/libstdc++-v3/include/std/algorithm +++
> > > b/libstdc++-v3/include/std/algorithm @@ -63,6 +63,7 @@ # include
> > > <bits/ranges_algo.h> #endif
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_clamp #define __glibcxx_want_constexpr_algorithms
> > > #define __glibcxx_want_freestanding_algorithm diff --git
> > > a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
> > > index 69f8c0dcdcc..48d2e308bdd 100644 ---
> > > a/libstdc++-v3/include/std/deque +++
> > > b/libstdc++-v3/include/std/deque @@ -68,6 +68,7 @@ #include
> > > <bits/range_access.h> #include <bits/deque.tcc>
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_allocator_traits_is_always_equal #define
> > > __glibcxx_want_erase_if #define
> > > __glibcxx_want_nonmember_container_access @@ -116,7 +117,8 @@
> > > _GLIBCXX_BEGIN_NAMESPACE_VERSION return 0; }
> > >  
> > > -  template<typename _Tp, typename _Alloc, typename _Up> +
> > > template<typename _Tp, typename _Alloc, typename _Up +
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_Tp)> inline typename
> > > deque<_Tp, _Alloc>::size_type erase(deque<_Tp, _Alloc>& __cont,
> > > const _Up& __value) { diff --git
> > > a/libstdc++-v3/include/std/forward_list
> > > b/libstdc++-v3/include/std/forward_list index
> > > dfd7d48d121..d03c965e82a 100644 ---
> > > a/libstdc++-v3/include/std/forward_list +++
> > > b/libstdc++-v3/include/std/forward_list @@ -45,6 +45,7 @@ #
> > > include <debug/forward_list> #endif
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_allocator_traits_is_always_equal #define
> > > __glibcxx_want_erase_if #define
> > > __glibcxx_want_incomplete_container_elements @@ -75,7 +76,8 @@
> > > _GLIBCXX_BEGIN_NAMESPACE_VERSION erase_if(forward_list<_Tp,
> > > _Alloc>& __cont, _Predicate __pred) { return
> > > __cont.remove_if(__pred); }
> > >  
> > > -  template<typename _Tp, typename _Alloc, typename _Up> +
> > > template<typename _Tp, typename _Alloc, typename _Up +
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_Tp)> inline typename
> > > forward_list<_Tp, _Alloc>::size_type erase(forward_list<_Tp,
> > > _Alloc>& __cont, const _Up& __value) { diff --git
> > > a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
> > > index ff632fc1ab2..e26ca11c468 100644 ---
> > > a/libstdc++-v3/include/std/list +++
> > > b/libstdc++-v3/include/std/list @@ -69,6 +69,7 @@ # include
> > > <debug/list> #endif
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_allocator_traits_is_always_equal #define
> > > __glibcxx_want_erase_if #define
> > > __glibcxx_want_incomplete_container_elements @@ -99,7 +100,8 @@
> > > _GLIBCXX_BEGIN_NAMESPACE_VERSION erase_if(list<_Tp, _Alloc>&
> > > __cont, _Predicate __pred) { return __cont.remove_if(__pred); }
> > >  
> > > -  template<typename _Tp, typename _Alloc, typename _Up> +
> > > template<typename _Tp, typename _Alloc, typename _Up +
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_Tp)> inline typename
> > > list<_Tp, _Alloc>::size_type erase(list<_Tp, _Alloc>& __cont,
> > > const _Up& __value) { diff --git a/libstdc++-v3/include/std/ranges
> > > b/libstdc++-v3/include/std/ranges index aa08a48440c..7169c3a92aa
> > > 100644 --- a/libstdc++-v3/include/std/ranges +++
> > > b/libstdc++-v3/include/std/ranges @@ -51,6 +51,7 @@ #include
> > > <bits/ranges_util.h> #include <bits/refwrap.h>
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_ranges #define __glibcxx_want_ranges_as_const
> > > #define __glibcxx_want_ranges_as_rvalue diff --git
> > > a/libstdc++-v3/include/std/string
> > > b/libstdc++-v3/include/std/string index 8db0802a282..461bf6450ae
> > > 100644 --- a/libstdc++-v3/include/std/string +++
> > > b/libstdc++-v3/include/std/string @@ -54,6 +54,7 @@ #include
> > > <bits/basic_string.h> #include <bits/basic_string.tcc>
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_allocator_traits_is_always_equal #define
> > > __glibcxx_want_constexpr_char_traits #define
> > > __glibcxx_want_constexpr_string @@ -105,7 +106,8 @@
> > > _GLIBCXX_BEGIN_NAMESPACE_VERSION return __osz - __cont.size(); }
> > >  
> > > -  template<typename _CharT, typename _Traits, typename _Alloc,
> > > typename _Up> +  template<typename _CharT, typename _Traits,
> > > typename _Alloc, typename _Up +
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_CharT)>
> > > _GLIBCXX20_CONSTEXPR inline typename basic_string<_CharT, _Traits,
> > > _Alloc>::size_type erase(basic_string<_CharT, _Traits, _Alloc>&
> > > __cont, const _Up& __value) diff --git
> > > a/libstdc++-v3/include/std/vector
> > > b/libstdc++-v3/include/std/vector index 906c1627935..60a21bd92d1
> > > 100644 --- a/libstdc++-v3/include/std/vector +++
> > > b/libstdc++-v3/include/std/vector @@ -76,6 +76,7 @@ # include
> > > <debug/vector> #endif
> > >  
> > > +#define __glibcxx_want_algorithm_default_value_type #define
> > > __glibcxx_want_allocator_traits_is_always_equal #define
> > > __glibcxx_want_constexpr_vector #define __glibcxx_want_erase_if @@
> > > -129,7 +130,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return 0; }
> > >  
> > > -  template<typename _Tp, typename _Alloc, typename _Up> +
> > > template<typename _Tp, typename _Alloc, typename _Up +
> > > _GLIBCXX26_ALGORITHM_DEFAULT_VALUE_TYPE(_Tp)> _GLIBCXX20_CONSTEXPR
> > > inline typename vector<_Tp, _Alloc>::size_type erase(vector<_Tp,
> > > _Alloc>& __cont, const _Up& __value) diff --git
> > > a/libstdc++-v3/testsuite/23_containers/default_template_value.cc
> > > b/libstdc++-v3/testsuite/23_containers/default_template_value.cc
> > > new file mode 100644 index 00000000000..b7615032686 --- /dev/null
> > > +++
> > > b/libstdc++-v3/testsuite/23_containers/default_template_value.cc
> > > @@ -0,0 +1,40 @@ +// { dg-do compile { target c++26 } } +
> > > +#include <deque> +#include <forward_list> +#include <list>
> > > +#include <string> +#include <vector> + +#if
> > > !defined(__cpp_lib_algorithm_default_value_type) +#error "Feature
> > > test macro for default template type for algorithms' values is
> > > missing" +#elif __cpp_lib_algorithm_default_value_type < 202403L
> > > +#error "Feature test macro for default template type for
> > > algorithms' values is wrong" +#endif + +struct S { +  S(int,
> > > double); +  friend auto operator<=>(const S&, const S&) = default;
> > > +}; + +template<template<typename...> typename Container> +void
> > > test_erase() +{ +  Container<S> c; +  std::erase(c, {1, 3.14}); +}
> > > + +void +test() +{ +  test_erase<std::deque>(); +
> > > test_erase<std::forward_list>(); +  test_erase<std::list>(); +
> > > test_erase<std::vector>(); + +  std::string s; +  std::erase(s,
> > > {'x'}); + +  std::wstring ws; +  std::erase(ws, {L'x'}); +} diff
> > > --git
> > > a/libstdc++-v3/testsuite/25_algorithms/default_template_value.cc
> > > b/libstdc++-v3/testsuite/25_algorithms/default_template_value.cc
> > > new file mode 100644 index 00000000000..3cf51bc087b --- /dev/null
> > > +++
> > > b/libstdc++-v3/testsuite/25_algorithms/default_template_value.cc
> > > @@ -0,0 +1,142 @@ +// { dg-do compile { target c++26 } } +
> > > +#include <algorithm> + +#if
> > > !defined(__cpp_lib_algorithm_default_value_type) +#error "Feature
> > > test macro for default template type for algorithms' values is
> > > missing" +#elif __cpp_lib_algorithm_default_value_type < 202403L
> > > +#error "Feature test macro for default template type for
> > > algorithms' values is wrong" +#endif + +#include <execution>
> > > +#include <ranges> +#include <iterator> +#include <vector> + +//
> > > Conversions from Input to Output will be used in certain
> > > algorithms.  +// Make Output have a different number of arguments
> > > to its constructor +// so we can check whether a braced-init-list
> > > is indeed matching Input +// or Output +struct Output +{ +
> > > Output(char, float, long); +}; + +#define OUTPUT_VAL {'x', 1.171f,
> > > 10L} + +struct Input +{ +  Input(int, double); +  friend bool
> > > operator<=>(const Input &, const Input &) = default; +  friend
> > > Input operator+(const Input &, const Input &); +  operator
> > > Output() const; +}; + +#define INPUT_VAL {1, 3.14} + +void +test()
> > > +{ +  extern std::vector<Input> in; +  extern std::vector<Output>
> > > out; + +  const auto pred = [](auto &&) { return true; }; + +  //
> > > [alg.find] +  (void) std::find(in.begin(), in.end(), INPUT_VAL); +
> > > (void) std::find(std::execution::seq, in.begin(), in.end(),
> > > INPUT_VAL); +  (void) std::ranges::find(in.begin(), in.end(),
> > > INPUT_VAL); +  (void) std::ranges::find(in, INPUT_VAL); + +  //
> > > [alg.count] +  (void) std::count(in.begin(), in.end(), INPUT_VAL);
> > > +  (void) std::count(std::execution::seq, in.begin(), in.end(),
> > > INPUT_VAL); +  (void) std::ranges::count(in.begin(), in.end(),
> > > INPUT_VAL); +  (void) std::ranges::count(in, INPUT_VAL); + +  //
> > > [alg.search] +  (void) std::search_n(in.begin(), in.end(), 10,
> > > INPUT_VAL); +  (void) std::search_n(in.begin(), in.end(), 10,
> > > INPUT_VAL, std::equal_to{}); +  (void)
> > > std::search_n(std::execution::seq, in.begin(), in.end(), 10,
> > > INPUT_VAL); +  (void) std::search_n(std::execution::seq,
> > > in.begin(), in.end(), 10, INPUT_VAL, std::equal_to{}); +  (void)
> > > std::ranges::search_n(in.begin(), in.end(), 10, INPUT_VAL); +
> > > (void) std::ranges::search_n(in, 10, INPUT_VAL); + +  //
> > > [alg.replace] +  (void) std::replace(in.begin(), in.end(),
> > > INPUT_VAL, INPUT_VAL); +  (void) std::replace(std::execution::seq,
> > > in.begin(), in.end(), INPUT_VAL, INPUT_VAL); +  (void)
> > > std::replace_if(in.begin(), in.end(), pred, INPUT_VAL); +  (void)
> > > std::replace_if(std::execution::seq, in.begin(), in.end(), pred,
> > > INPUT_VAL); + +  (void) std::ranges::replace(in.begin(), in.end(),
> > > INPUT_VAL, INPUT_VAL); +  (void) std::ranges::replace(in,
> > > INPUT_VAL, INPUT_VAL); +  (void)
> > > std::ranges::replace_if(in.begin(), in.end(), pred, INPUT_VAL); +
> > > (void) std::ranges::replace_if(in, pred, INPUT_VAL); + +  (void)
> > > std::replace_copy_if(in.begin(), in.end(), out.begin(), pred,
> > > OUTPUT_VAL); +  (void) std::replace_copy_if(std::execution::seq,
> > > in.begin(), in.end(), out.begin(), pred, OUTPUT_VAL); +  (void)
> > > std::ranges::replace_copy_if(in.begin(), in.end(), out.begin(),
> > > pred, OUTPUT_VAL); +  (void) std::ranges::replace_copy_if(in,
> > > out.begin(), pred, OUTPUT_VAL); + +  // Non-range replace_copy is
> > > deliberately skipped by P2248 +  (void)
> > > std::ranges::replace_copy(in.begin(), in.end(), out.begin(),
> > > INPUT_VAL, OUTPUT_VAL); +  (void) std::ranges::replace_copy(in,
> > > out.begin(), INPUT_VAL, OUTPUT_VAL); + +  // [alg.fill] +  (void)
> > > std::fill(in.begin(), in.end(), INPUT_VAL); +  (void)
> > > std::fill(std::execution::seq, in.begin(), in.end(), INPUT_VAL); +
> > > (void) std::ranges::fill(in.begin(), in.end(), INPUT_VAL); +
> > > (void) std::ranges::fill(in, INPUT_VAL); + +  (void)
> > > std::fill_n(in.begin(), 10, INPUT_VAL); +  (void)
> > > std::fill_n(std::execution::seq, in.begin(), 10, INPUT_VAL); +
> > > (void) std::ranges::fill_n(in.begin(), 10, INPUT_VAL); + +  //
> > > [alg.remove] +  (void) std::remove(in.begin(), in.end(),
> > > INPUT_VAL); +  (void) std::remove(std::execution::seq, in.begin(),
> > > in.end(), INPUT_VAL); +  (void) std::ranges::remove(in.begin(),
> > > in.end(), INPUT_VAL); +  (void) std::ranges::remove(in,
> > > INPUT_VAL); + +  (void) std::remove_copy(in.begin(), in.end(),
> > > out.begin(), INPUT_VAL); +  (void)
> > > std::remove_copy(std::execution::seq, in.begin(), in.end(),
> > > out.begin(), INPUT_VAL); +  (void)
> > > std::ranges::remove_copy(in.begin(), in.end(), out.begin(),
> > > INPUT_VAL); +  (void) std::ranges::remove_copy(in, out.begin(),
> > > INPUT_VAL); + +  // [alg.binary.search] +  (void)
> > > std::lower_bound(in.begin(), in.end(), INPUT_VAL); +  (void)
> > > std::lower_bound(in.begin(), in.end(), INPUT_VAL, std::less{}); +
> > > (void) std::ranges::lower_bound(in.begin(), in.end(), INPUT_VAL);
> > > +  (void) std::ranges::lower_bound(in, INPUT_VAL); + +  (void)
> > > std::upper_bound(in.begin(), in.end(), INPUT_VAL); +  (void)
> > > std::upper_bound(in.begin(), in.end(), INPUT_VAL, std::less{}); +
> > > (void) std::ranges::upper_bound(in.begin(), in.end(), INPUT_VAL);
> > > +  (void) std::ranges::upper_bound(in, INPUT_VAL); + +  (void)
> > > std::equal_range(in.begin(), in.end(), INPUT_VAL); +  (void)
> > > std::equal_range(in.begin(), in.end(), INPUT_VAL, std::less{}); +
> > > (void) std::ranges::equal_range(in.begin(), in.end(), INPUT_VAL);
> > > +  (void) std::ranges::equal_range(in, INPUT_VAL); + +  (void)
> > > std::binary_search(in.begin(), in.end(), INPUT_VAL); +  (void)
> > > std::binary_search(in.begin(), in.end(), INPUT_VAL, std::less{});
> > > +  (void) std::ranges::binary_search(in.begin(), in.end(),
> > > INPUT_VAL); +  (void) std::ranges::binary_search(in, INPUT_VAL); +
> > > +  // [alg.fold] +  (void) std::ranges::fold_left(in.begin(),
> > > in.end(), INPUT_VAL, std::plus<>{}); +  (void)
> > > std::ranges::fold_left(in, INPUT_VAL, std::plus<>{}); +  (void)
> > > std::ranges::fold_right(in.begin(), in.end(), INPUT_VAL,
> > > std::plus<>{}); +  (void) std::ranges::fold_right(in, INPUT_VAL,
> > > std::plus<>{}); +  (void)
> > > std::ranges::fold_left_with_iter(in.begin(), in.end(), INPUT_VAL,
> > > std::plus<>{}); +  (void) std::ranges::fold_left_with_iter(in,
> > > INPUT_VAL, std::plus<>{}); + +  // [alg.contains] +  (void)
> > > std::ranges::contains(in.begin(), in.end(), INPUT_VAL); +  (void)
> > > std::ranges::contains(in, INPUT_VAL); + +  // [alg.find.last] +
> > > (void) std::ranges::find_last(in.begin(), in.end(), INPUT_VAL); +
> > > (void) std::ranges::find_last(in, INPUT_VAL); +}
> > 
> 

Reply via email to