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

FreeBSD Manual Pages

  
 
  

home | help
std::ranges::is_heap_until(3) C++ Standard Libarystd::ranges::is_heap_until(3)

NAME
       std::ranges::is_heap_until - std::ranges::is_heap_until

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

		    class  Proj	= std::identity, std::indirect_strict_weak_or-
       der<	  (since
		    std::projected<I,	Proj>>	 Comp	=    ranges::less    >
       (1) C++20)
	  constexpr I

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

	  std::indirect_strict_weak_order<std::projected<ranges::itera-
       tor_t<R>,	(since
	  Proj>>
       (2) C++20)
		    Comp = ranges::less	>
	  constexpr ranges::borrowed_iterator_t<R>

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

	  Examines the range [first, last) and finds the largest range	begin-
       ning at first
	  which	is a max heap.

	  1)  Elements are compared using the given binary comparison function
       comp and
	  projection object proj.
	  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 -	the range of elements to examine
	  r	      -	the range of elements to examine
	  pred	      -	predicate to apply to the projected elements
	  proj	      -	projection to apply to the elements

Return value
	  The upper bound of the largest range beginning at first which	 is  a
       max heap. That
	  is,  the  last iterator it for which range [first, it) is a max heap
       with respect to
	  comp and proj.

Complexity
	  Linear in the	distance between first and last.

Notes
	  A max	heap is	a range	of elements [f,	l), arranged with  respect  to
       comparator comp
	  and projection proj, that has	the following properties:

	    *  With N =	l - f, p = f[(i	- 1) / 2], and q = f[i], for all 0 < i
       < N, the
	      expression  std::invoke(comp,  std::invoke(proj,	p),   std::in-
       voke(proj, q))
	      evaluates	to false.
	    *	A  new	element	 can  be  added	 using	ranges::push_heap,  in
       \(\scriptsize
	      \mathcal{O}(\log N)\)(log	N) time.
	    * The first	element	can  be	 removed  using	 ranges::pop_heap,  in
       \(\scriptsize
	      \mathcal{O}(\log N)\)(log	N) time.

Possible implementation
       struct is_heap_until_fn {
	   template<std::random_access_iterator	I, std::sentinel_for<I>	S,
		    class  Proj	= std::identity, std::indirect_strict_weak_or-
       der<
		    std::projected<I, Proj>> Comp = ranges::less>
	   constexpr I
	       operator()(I first, S last, Comp	comp = {},  Proj  proj	=  {})
       const
	   {
	       std::iter_difference_t<I>   n{ranges::distance(first,   last)},
       dad{0}, son{1};
	       for (; son != n;	++son)
	       {
		   if (std::invoke(comp, std::invoke(proj, *(first + dad)),
					 std::invoke(proj, *(first + son))))
		       return first + son;
		   else	if ((son % 2) == 0)
		       ++dad;
	       }
	       return first + n;
	   }

	   template<ranges::random_access_range	R, class Proj =	std::identity,
		    std::indirect_strict_weak_order<std::projected<ranges::it-
       erator_t<R>, Proj>>
		    Comp = ranges::less>
	   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	is_heap_until_fn is_heap_until {};

Example
	  The example renders a	given vector as	a (balanced) Binary tree.

       // Run this code

	#include <algorithm>
	#include <cmath>
	#include <iostream>
	#include <iterator>
	#include <vector>

	void out(const auto& what, int n = 1)
	{
	    while (n-- > 0)
		std::cout << what;
	}

	void draw_bin_tree(auto	first, auto last)
	{
	    auto bails = [](int	n, int w)
	    {
		auto b = [](int	w) { out(""), out("", w), out(""), out("", w),
       out("");	};
		n /= 2;
		if (!n)
		    return;
		for (out(' ', w); n-- >	0;)
		    b(w), out('	', w + w + 1);
		out('\n');
	    };
	    auto data =	[](int n, int w, auto& first, auto last)
	    {
		for (out(' ', w); n-- >	0 && first != last; ++first)
		    out(*first), out(' ', w + w	+ 1);
		out('\n');
	    };
	    auto tier =	[&](int	t, int m, auto&	first, auto last)
	    {
		const int n{1 << t};
		const int w{(1 << (m - t - 1)) - 1};
		bails(n, w), data(n, w,	first, last);
	    };
	    const auto size{std::ranges::distance(first, last)};
	    const int m{static_cast<int>(std::ceil(std::log2(1 + size)))};
	    for	(int i{}; i != m; ++i)
		tier(i,	m, first, last);
	}

	int main()
	{
	    std::vector<int> v{3, 1, 4,	1, 5, 9};
	    std::ranges::make_heap(v);

	    // probably	mess up	the heap
	    v.push_back(2);
	    v.push_back(6);

	    out("v after make_heap and push_back:\n");
	    draw_bin_tree(v.begin(), v.end());

	    out("the max-heap prefix of	v:\n");
	    const auto heap_end	= std::ranges::is_heap_until(v);
	    draw_bin_tree(v.begin(), heap_end);
	}

Output:
	v after	make_heap and push_back:
	       9

	   5	   4

	 1   1	 3   2

	6
	the max-heap prefix of v:
	   9

	 5   4

	1 1 3 2

See also
	  ranges::is_heap   checks if the given	range is a max heap
	  (C++20)	    (niebloid)
	  ranges::make_heap creates a max heap out of a	range of elements
	  (C++20)	    (niebloid)
	  ranges::push_heap adds an element to a max heap
	  (C++20)	    (niebloid)
	  ranges::pop_heap  removes the	largest	element	from a max heap
	  (C++20)	    (niebloid)
	  ranges::sort_heap  turns  a max heap into a range of elements	sorted
       in ascending
	  (C++20)	    order
			    (niebloid)
	  is_heap_until	    finds the largest subrange that is a max heap
	  (C++11)	    (function template)

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

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

home | help