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

FreeBSD Manual Pages

  
 
  

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

NAME
       std::ranges::sort - std::ranges::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	>
	  requires	      std::sortable<I,		 Comp,		 Proj>
       (1) (since C++20)
	  constexpr I

	  sort(	I first, S last, Comp comp = {}, Proj proj = {}	);
	  template< ranges::random_access_range	R, class Comp =
	  ranges::less,

	  class		  Proj		 =	     std::identity	     >
       (2) (since C++20)
	  requires std::sortable<ranges::iterator_t<R>,	Comp, Proj>
	  constexpr ranges::borrowed_iterator_t<R>

	  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 not 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  source range, as if using
       ranges::begin(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 may not be specified when call-
       ing any of them.
	    * None of them is visible to argument-dependent lookup.
	    *  When  one of them is found by normal unqualified	lookup for the
       name to the left
	      of the function-call operator,  it  inhibits  argument-dependent
       lookup.

	  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	 \mathcal{O}(N\cdot\log{(N)})\)(Nlog(N))   comparisons
       and
	  projections, where N = ranges::distance(first, last).

Possible implementation
	  Note that typical implementations use	introsort. See also the	imple-
       mentation in MSVC
	  STL and libstdc++.

       struct 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 I
	   operator()( I first,	S last,	Comp comp = {},	Proj proj = {} ) const
       {
	       if (first == last)
		   return first;

	       I last_iter = ranges::next(first, last);
	       ranges::make_heap(first,	      last_iter,       std::ref(comp),
       std::ref(proj));
	       ranges::sort_heap(first,	      last_iter,       std::ref(comp),
       std::ref(proj));

	       return last_iter;
	   }

	   template< ranges::random_access_range R, class Comp = ranges::less,
		     class Proj	= std::identity	>
	   requires std::sortable<ranges::iterator_t<R>, Comp, Proj>
	   constexpr 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	sort_fn	sort{};

Notes
	  std::sort uses std::iter_swap	to swap	elements, whereas ranges::sort
       instead uses
	  ranges::iter_swap  (which  performs  ADL   for   iter_swap,	unlike
       std::iter_swap)

Example
       // Run this code

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

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

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

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

	    namespace ranges = std::ranges;

	    ranges::sort(s);
	    print("Sort	using the default operator<", s);

	    ranges::sort(s, ranges::greater());
	    print("Sort	using a	standard library compare function object", s);

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

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

	    Particle particles[] {
		{"Electron", 0.511}, {"Muon", 105.66}, {"Tau", 1776.86},
		{"Positron", 0.511}, {"Proton",	938.27}, {"Neutron", 939.57},
	    };
	    ranges::sort(particles, {},	&Particle::name);
	    print("\nSort by name using	a projection", particles, '\n');
	    ranges::sort(particles, {},	&Particle::mass);
	    print("Sort	by mass	using a	projection", particles,	'\n');
	}

Output:
	Sort using the default operator<
	0 1 2 3	4 5 6 7	8 9
	Sort using a standard library compare function object
	9 8 7 6	5 4 3 2	1 0
	Sort using a custom function object
	0 1 2 3	4 5 6 7	8 9
	Sort using a lambda expression
	9 8 7 6	5 4 3 2	1 0

	Sort by	name using a projection
	Electron : 0.511
	Muon	 : 105.66
	Neutron	 : 939.57
	Positron : 0.511
	Proton	 : 938.27
	Tau	 : 1776.86

	Sort by	mass using a projection
	Electron : 0.511
	Positron : 0.511
	Muon	 : 105.66
	Proton	 : 938.27
	Neutron	 : 939.57
	Tau	 : 1776.86

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

http://cppreference.com		  2022.07.31		  std::ranges::sort(3)

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

home | help