template<class ForwardIterator, class UnaryOperation>
ForwardIterator arg_min(ForwardIterator first, ForwardIterator last,
UnaryOperation op)
{
if (first == last)
return last;
auto arg = first;
auto minima = op(*first++);
for (; first != last; ++first) {
auto value = op(*first);
if (value < minima) {
arg = first;
minima = value;
}
}
return arg;
}
struct rgb { float r, g, b; };
rgb map_to_palette(rgb const from, vector<rgb> const &palette)
{
assert(!palette.empty());
return *arg_min(begin(palette), end(palette), [&](rgb to) {
return ((to.r - from.r) * (to.r - from.r) +
(to.g - from.g) * (to.g - from.g) +
(to.b - from.b) * (to.b - from.b));
});
}
On 2015–07–30, at 1:07 AM, Erich Keane <erich...@verizon.net> wrote:Perhaps I'm reading this wrong, but it seems that it does the same thing as std::min_element.
rgb map_to_palette(rgb const from, vector<rgb> const &palette)
{
assert(!palette.empty());
auto diff = [&](rgb to) {
return ((to.r - from.r) * (to.r - from.r) +
(to.g - from.g) * (to.g - from.g) +
(to.b - from.b) * (to.b - from.b));
};
return *min_element(begin(palette), end(palette), [&](rgb left, rgb right) {
return diff(left) < diff(right);
});
}
On the other hand, arg_min() is sufficiently powerful that one can express min_element() in terms of it by passing in a simple identity function as the operation.
With that in mind, I did consider suggesting these as new overloads of min_element() and max_element(). However, I believe that disambiguating whether the function passed is a comparator or a unary op requires either either arbitrarily re-ordering the parameters or else using an empty tag struct (similar to piecewise_constructor for tuples). Neither one strikes me as a particularly great option and arg_min() and arg_max() at least have the advantage of implying the mapping.
auto p = std::max_element(
boost::make_transform_iterator(first, func),
boost::make_transform_iterator(last, func)).base();
auto p = boost::max_element(data | boost::adaptors::transformed(func));So, a caching_iterator<transform_iterator<first, func>> should be
enough to call func no more than N times.