Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::ranges::stable_sort(3)   C++ Standard Libary  std::ranges::stable_sort(3)

NAME
       std::ranges::stable_sort	- std::ranges::stable_sort

Synopsis
	  Defined in header <algorithm>
	  Call signature
	  template< std::random_access_iterator	I, std::sentinel_for<I>
	  S,

		    class  Comp	 =  ranges::less,  class  Proj = std::identity
       (since C++20)
	  >								   (1)
       (constexpr since
	  requires	      std::sortable<I,		 Comp,		 Proj>
       C++26)

	      I	stable_sort( I first, S	last, Comp comp	= {}, Proj proj	=
	  {} );
	  template< ranges::random_access_range	R, class Comp =
	  ranges::less,
									      (since
       C++20)
		    class Proj = std::identity >			   (2)
       (constexpr since
	  requires     std::sortable<ranges::iterator_t<R>,	Comp,	 Proj>
       C++26)
	  ranges::borrowed_iterator_t<R>

	      stable_sort( R&& r, Comp comp = {}, Proj proj = {} );

	  Sorts	the elements in	the range [first, last)	in non-descending  or-
       der. The	order of
	  equivalent elements is stable, i.e. guaranteed to be preserved.

	  A  sequence  is  sorted with respect to a comparator comp if for any
       iterator	it
	  pointing to the sequence and any non-negative	integer	n such that it
       + n is a	valid
	  iterator pointing to an element of the  sequence,  std::invoke(comp,
       std::invoke(proj,
	  *(it + n)), std::invoke(proj,	*it) evaluates to false.

	  1)  Elements are compared using the given binary comparison function
       comp.
	  2) Same as (1), but uses r as	the range,  as	if  using  ranges::be-
       gin(r) as first and
	  ranges::end(r) as last.

	  The  function-like  entities	described  on this page	are niebloids,
       that is:

	    * Explicit template	argument lists cannot be specified when	 call-
       ing any of them.
	    * None of them are visible to argument-dependent lookup.
	    *  When  any of them are found by normal unqualified lookup	as the
       name to the left
	      of the function-call operator, argument-dependent	lookup is  in-
       hibited.

	  In  practice,	 they  may be implemented as function objects, or with
       special compiler
	  extensions.

Parameters
	  first, last -	iterator-sentinel defining the range to	sort
	  r	      -	the range to sort
	  comp	      -	comparison to apply to the projected elements
	  proj	      -	projection to apply to the elements

Return value
	  An iterator equal to last.

Complexity
	  \(\scriptsize	N\cdot\log{(N)}\)Nlog(N) comparisons, if extra	memory
       is available;
	  where	  \(\scriptsize	  N\)N	 is   ranges::distance(first,	last).
       \(\scriptsize
	  N\cdot\log^2{(N)}\)Nlog(N) comparisons otherwise. Twice as many pro-
       jections	as the
	  number of comparisons	in both	cases.

Notes
		Feature-test macro	  Value	 Std	     Feature
	  __cpp_lib_constexpr_algorithms 202306L     constexpr stable sorting

Possible implementation
	  This implementation only shows the slower algorithm used when	no ad-
       ditional	memory
	  is available.	See also implementation	in MSVC	STL and	libstdc++.

       struct stable_sort_fn {
	   template<std::random_access_iterator	I, std::sentinel_for<I>	S,
		    class Comp = ranges::less, class Proj = std::identity>
	   requires std::sortable<I, Comp, Proj>
	   constexpr //< since C++26
	   I operator()(I first, S last, Comp comp = {}, Proj proj = {}) const
	   {
	       auto count = ranges::distance(first, last);
	       auto mid	= first	+ count	/ 2;
	       auto last_it = first + count;

	       if (count <= 1)
		   return last_it;

	       (*this)(first, mid, std::ref(comp), std::ref(proj));
	       (*this)(mid, last_it, std::ref(comp), std::ref(proj));

	       ranges::inplace_merge(first, mid, last_it);

	       return last_it;
	   }

	   template<ranges::random_access_range	R, class Comp =	ranges::less,
		    class Proj = std::identity>
	   requires std::sortable<ranges::iterator_t<R>, Comp, Proj>
	   constexpr //< since C++26
	   ranges::borrowed_iterator_t<R> operator()(R&& r, Comp  comp	=  {},
       Proj proj = {}) const
	   {
	       return	      (*this)(ranges::begin(r),	       ranges::end(r),
       std::move(comp),	std::move(proj));
	   } };

       inline constexpr	stable_sort_fn stable_sort {};

Example
       // Run this code

	#include <algorithm>
	#include <array>
	#include <functional>
	#include <iomanip>
	#include <iostream>

	void print(auto	const& seq)
	{
	    for	(auto const& elem : seq)
		std::cout << elem << ' ';
	    std::cout << '\n';
	}

	struct Particle
	{
	    std::string	name; double mass; // MeV
	    friend std::ostream& operator<<(std::ostream& os, Particle	const&
       p)
	    {
		return	os << '\n' << std::left	<< std::setw(8)	<< p.name << "
       : " << p.mass;
	    }
	};

	int main()
	{
	    std::array s {5, 7,	4, 2, 8, 6, 1, 9, 0, 3};

	    // sort using the default operator<
	    std::ranges::stable_sort(s);
	    print(s);

	    // sort using a standard library compare function object
	    std::ranges::stable_sort(s,	std::ranges::greater());
	    print(s);

	    // sort using a custom function object
	    struct
	    {
		bool operator()(int a, int b) const
		{
		    return a < b;
		}
	    } customLess;
	    std::ranges::stable_sort(s.begin(),	s.end(), customLess);
	    print(s);

	    // sort using a lambda expression
	    std::ranges::stable_sort(s,	[](int a, int b) { return a > b; });
	    print(s);

	    // sort with projection
	    Particle particles[]
	    {
		{"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86},
		{"Positron", 0.511}, {"Proton",	938.27}, {"Neutron", 939.57}
	    };
	    print(particles);
	    std::ranges::stable_sort(particles,	{}, &Particle::name); //< sort
       by name
	    print(particles);
	    std::ranges::stable_sort(particles,	{}, &Particle::mass); //< sort
       by mass
	    print(particles);
	}

Output:
	0 1 2 3	4 5 6 7	8 9
	9 8 7 6	5 4 3 2	1 0
	0 1 2 3	4 5 6 7	8 9
	9 8 7 6	5 4 3 2	1 0

	Electron : 0.511
	Muon	 : 105.66
	Tau	 : 1776.86
	Positron : 0.511
	Proton	 : 938.27
	Neutron	 : 939.57

	Electron : 0.511
	Muon	 : 105.66
	Neutron	 : 939.57
	Positron : 0.511
	Proton	 : 938.27
	Tau	 : 1776.86

	Electron : 0.511
	Positron : 0.511
	Muon	 : 105.66
	Proton	 : 938.27
	Neutron	 : 939.57
	Tau	 : 1776.86

See also
	  ranges::sort		   sorts a range into ascending	order
	  (C++20)		   (niebloid)
	  ranges::partial_sort	   sorts the first N elements of a range
	  (C++20)		   (niebloid)
	  ranges::stable_partition divides elements into two groups while pre-
       serving their
	  (C++20)		   relative order
				   (niebloid)
				   sorts a range of elements while  preserving
       order between
	  stable_sort		   equal elements
				   (function template)

http://cppreference.com		  2024.06.10	   std::ranges::stable_sort(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::ranges::stable_sort&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help