Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #82503

Re: equal_range sucks !

From Bonita Montero <Bonita.Montero@gmail.com>
Newsgroups comp.lang.c++
Subject Re: equal_range sucks !
Date 2021-11-28 17:04 +0100
Organization A noiseless patient Spider
Message-ID <so09ao$46m$2@dont-email.me> (permalink)
References <snivjr$afv$1@dont-email.me> <snvpjf$14uo6$1@gwaiyur.mb-net.net>

Show all headers | View raw


Am 28.11.2021 um 12:36 schrieb Marcel Mueller:
> Am 23.11.21 um 15:59 schrieb Bonita Montero:
>> I just tried this:
>>
>>      pair<cpu_it, cpu_it> foundApicId = equal_range( apicIds.begin(), 
>> apicIds.end(),
>>          apicId, []( cpu_apic_id const &idRange, unsigned apicId ) { 
>> return idRange.apicId == apicId; } );
>>
>> It should be possible that the key for the range has a different type
>> than than the elemnens in the range so that I can compare against a
>> part of the range-objects like in the above code.
> 
> Feel free to write an asymmetric comparer that fits your needs.
> 
> You may also implement an asymmetric operator<, but implicitly comparing 
> apples with oranges is not a good advice.

I've written an asymmetric version:

template<typename RandomIt, typename T, typename Pred>
std::pair<RandomIt, RandomIt> xequal_range( RandomIt begin, RandomIt 
end, T const &key, Pred pred )
	requires std::random_access_iterator<RandomIt>
	&&
	requires( Pred pred, typename 
std::iterator_traits<RandomIt>::value_type &elem, T const &key )
	{
		{ pred( elem, key ) } -> std::convertible_to<std::strong_ordering>;
	}
{
	using namespace std;
	assert(end >= begin);
	size_t hit = -1, lower = 0, upper = end - begin, mid;
	strong_ordering so;
	while( lower != upper )
	{
		mid = lower + (upper - lower) / 2;
		so = pred( begin[mid], key );
		if( so >= 0 )
		{
			if( so == 0 )
				hit = mid;
			upper = mid;
		}
		else
			lower = mid + 1;
	}
	if( hit == -1 )
		return pair<RandomIt, RandomIt>( end, end );
	begin += hit;
	hit = 0, lower = 1, upper = end - begin;
	while( lower != upper )
	{
		mid = (lower + upper) / 2;
		so = pred( begin[mid], key );
		if( so > 0 )
			upper = mid;
		else
			assert(so == 0),
			hit = mid,
			lower = mid + 1;
	}
	end = begin + hit + 1;
	return pair<RandomIt, RandomIt>( begin, end );
}

Back to comp.lang.c++ | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-23 15:59 +0100
  Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-23 16:04 +0100
    Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-23 17:13 +0100
      Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-23 19:53 +0100
        Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-25 15:02 +0100
      Re: equal_range sucks ! Juha Nieminen <nospam@thanks.invalid> - 2021-11-24 08:06 +0000
        Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-24 18:18 +0100
  Re: equal_range sucks ! Marcel Mueller <news.5.maazl@spamgourmet.org> - 2021-11-28 12:36 +0100
    Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-28 17:04 +0100
      Re: equal_range sucks ! Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-28 17:23 +0100

csiph-web