Commit fe7a278f authored by Philip Trettner's avatar Philip Trettner
Browse files

min_by, max_by, minmax_by

parent ab7103b9
......@@ -131,6 +131,85 @@ auto smart_range<this_t, ElementT>::sum(FuncT &&f) const -> tmp::decayed_result_
return s;
}
template <class this_t, class ElementT>
template <class FuncT>
ElementT smart_range<this_t, ElementT>::min_by(FuncT &&f) const
{
auto it_begin = static_cast<this_t const *>(this)->begin();
auto it_end = static_cast<this_t const *>(this)->end();
assert(it_begin != it_end && "requires non-empty range");
auto e_min = *it_begin;
auto v_min = f(e_min);
++it_begin;
while (it_begin != it_end)
{
auto e = *it_begin;
auto v = f(*it_begin);
if (v < v_min)
{
v_min = v;
e_min = e;
}
++it_begin;
}
return e_min;
}
template <class this_t, class ElementT>
template <class FuncT>
ElementT smart_range<this_t, ElementT>::max_by(FuncT &&f) const
{
auto it_begin = static_cast<this_t const *>(this)->begin();
auto it_end = static_cast<this_t const *>(this)->end();
assert(it_begin != it_end && "requires non-empty range");
auto e_max = *it_begin;
auto v_max = f(e_max);
++it_begin;
while (it_begin != it_end)
{
auto e = *it_begin;
auto v = f(*it_begin);
if (v > v_max)
{
v_max = v;
e_max = e;
}
++it_begin;
}
return e_max;
}
template <class this_t, class ElementT>
template <class FuncT>
polymesh::aabb<ElementT> smart_range<this_t, ElementT>::minmax_by(FuncT &&f) const
{
auto it_begin = static_cast<this_t const *>(this)->begin();
auto it_end = static_cast<this_t const *>(this)->end();
assert(it_begin != it_end && "requires non-empty range");
auto e_min = *it_begin;
auto e_max = e_min;
auto v_min = f(e_min);
auto v_max = v_min;
++it_begin;
while (it_begin != it_end)
{
auto e = *it_begin;
auto v = f(*it_begin);
if (v < v_min)
{
v_min = v;
e_min = e;
}
if (v > v_max)
{
v_max = v;
e_max = e;
}
++it_begin;
}
return {e_min, e_max};
}
template <class this_t, class ElementT>
template <class FuncT>
auto smart_range<this_t, ElementT>::avg(FuncT &&f) const -> tmp::decayed_result_type_of<FuncT, ElementT>
......
......@@ -57,11 +57,21 @@ struct smart_range
/// works for std::min and everything reachable by ADL (calls min(_, _))
template <class FuncT>
auto min(FuncT&& f) const -> tmp::decayed_result_type_of<FuncT, ElementT>;
/// returns e that minimizes f(e)
/// undefined behavior if range is empty
/// requires working comparison operators for the result
template <class FuncT>
ElementT min_by(FuncT&& f) const;
/// calculates max(f(e)) over all elements
/// undefined behavior if range is empty
/// works for std::max and everything reachable by ADL (calls max(_, _))
template <class FuncT>
auto max(FuncT&& f) const -> tmp::decayed_result_type_of<FuncT, ElementT>;
/// returns e that maximizes f(e)
/// undefined behavior if range is empty
/// requires working comparison operators for the result
template <class FuncT>
ElementT max_by(FuncT&& f) const;
/// calculates the sum of f(e) over all elements
/// undefined behavior if range is empty
/// requires operator+ for the elements
......@@ -87,6 +97,11 @@ struct smart_range
/// same as aabb(...)
template <class FuncT>
auto minmax(FuncT&& f) const -> polymesh::aabb<tmp::decayed_result_type_of<FuncT, ElementT>>;
/// returns {e_min, e_max} that minimizes/maximizes f(e)
/// undefined behavior if range is empty
/// requires working comparison operators for the result
template <class FuncT>
polymesh::aabb<ElementT> minmax_by(FuncT&& f) const;
/// converts this range to a vector
std::vector<ElementT> to_vector() const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment