smart range improvements

This commit is contained in:
Max Lyon
2019-09-27 16:34:20 +02:00
parent f71696f294
commit b5b708a6ba
2 changed files with 145 additions and 1 deletions

View File

@@ -43,6 +43,8 @@
#pragma once
#include <utility>
#include <array>
#include <vector>
//== NAMESPACES ===============================================================
@@ -52,12 +54,24 @@ namespace OpenMesh {
//== CLASS DEFINITION =========================================================
namespace {
struct Identity
{
template <typename T>
T operator()(const T& _t) const { return _t; }
};
}
/// Base class for all smart range types
template <typename RangeT, typename HandleT>
struct SmartRangeT
{
// TODO: Someone with better c++ knowledge may improve the code below.
template <typename Functor>
auto sum(Functor&& f) -> decltype (f(std::declval<HandleT>())+f(std::declval<HandleT>()))
{
@@ -92,6 +106,74 @@ struct SmartRangeT
return (1.0 / n_elements) * sum;
}
template <int n, typename Functor = Identity>
auto to_array(Functor&& f = {}) -> std::array<typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type, n>
{
auto range = static_cast<const RangeT*>(this);
std::array<typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type, n> res;
auto it = range->begin();
auto end = range->end();
int i = 0;
while (i < n && it != end)
res[i++] = f(*(it++));
return res;
}
template <typename Functor = Identity>
auto to_vector(Functor&& f = {}) -> std::vector<typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type>
{
auto range = static_cast<const RangeT*>(this);
std::vector<typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type> res;
for (auto e : *range)
res.push_back(f(e));
return res;
}
template <int n, typename Functor>
auto elem_wise_min(Functor&& f) -> typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type
{
auto range = static_cast<const RangeT*>(this);
auto it = range->begin();
auto end = range->end();
assert(it != end);
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type min = f(*it);
++it;
for (; it != end; ++it)
{
const auto& tmp = f(*it);
for (int i = 0; i < n; ++i)
min[i] = std::min(min[i], tmp[i]);
}
return min;
}
template <int n, typename Functor>
auto elem_wise_max(Functor&& f) -> typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type
{
auto range = static_cast<const RangeT*>(this);
auto it = range->begin();
auto end = range->end();
assert(it != end);
typename std::remove_reference<decltype (f(std::declval<HandleT>()))>::type max = f(*it);
++it;
for (; it != end; ++it)
{
const auto& tmp = f(*it);
for (int i = 0; i < n; ++i)
max[i] = std::max(max[i], tmp[i]);
}
return max;
}
};