I am looking for a way to do a binary search over function results with a signature close to the following:
template <class ArgT,
class ResultT,
class TransformFunc,
class Compare = std::less<ResultT>>
ArgT
result_upper_bound(ResultT searched, ArgT begin, ArgT end, TransformFunc tf, Compare comp);
The function is expected to return a first arg in the range [begin, end) which gives TransformFunc
result that does not satisfy result
> searched
.
I have succeded in doing this task by implementing iterator over integers and using std::ranges::views::transform
and std::ranges::upper_bound
. The problim is that this solution does not work with clang
becuse ranges
library is not correctly supported by this compiler and will not be until clang 16
is released. By the way, the code is close to this:
...
auto argsRng = std::ranges::subrange<MyIntIt<uint64_t>>(
MyIntIt<uint64_t>(0), MyIntIt<uint64_t>(Conditions::bigNumber));
const auto func = [](uint64_t index) {
return Conditions::func(index);
};
auto transformed =
std::ranges::views::transform(argsRng, func);
auto it = std::ranges::upper_bound(transformed, searchedArg);
...
boost::transform_iterator
and boost::range::adaptors::transform
are not exactly RandomAccess. That means their usage instead of std::ranges::views::transform
makes std::lower_bound
non-effective.
What are other ways of implementing this without writing binary search?