Commit d773c643 by Praetorius, Simon

### Move all recursive algorithms to algorithm subdirectory

parent 1a410159
 #pragma once #include #include #include #include #include namespace AMDiS { namespace Recursive { template struct Apply; /// \brief Recursive application of a transformation functor f to a hierarchic /// container of containers, returning the transformed container. /** * This utility function applies the given functor f to the "leaf" entries in * a hierarchic container that returns a transformed container. Therefore, the * container is traversed recursively, using specializations of the Apply::impl * class method. If no specialization is provided, the function is applied to the * whole container or leaf entry, respectively. **/ template auto apply(F&& f, T const& t) { return Apply::impl(f,t); } // specializations for container types /// Default implementation of the recursive \ref map function. template struct Apply { template static auto impl(F&& f, T const& t) { return f(t); } }; template struct Apply> { template static auto impl(F&& f, std::array const& a) { return Ranges::applyIndices([&](auto... ii) { return std::array{Recursive::apply(f,a[ii])...}; }); } }; template struct Apply> { template static auto impl(F&& f, std::tuple const& t) { return Ranges::apply([&](auto const&... ti) { return std::tuple{Recursive::apply(f,ti)...}; }, t); } }; template struct Apply> { template static auto impl(F&& f, std::pair const& t) { return std::pair{Recursive::apply(f,t.first), Recursive::apply(f,t.second)}; } }; template struct Apply> { template static auto impl(F&& f, Dune::TupleVector const& t) { return Ranges::apply([&](auto const&... ti) { return Dune::makeTupleVector(Recursive::apply(f,ti)...); }, t); } }; template struct Apply> { template static auto impl(F&& f, std::vector const& v) { using U = TYPEOF(Recursive::apply(f,std::declval())); std::vector out; out.reserve(v.size()); for (std::size_t i = 0; i < v.size(); ++i) out.emplace_back(Recursive::apply(f,v[i])); return out; } }; }} // end namespace AMDiS::Recursive \ No newline at end of file
 install(FILES Apply.hpp ForEach.hpp InnerProduct.hpp Transform.hpp DESTINATION \${CMAKE_INSTALL_INCLUDEDIR}/amdis/algorithm)
 #pragma once #include #include #include #include #include #include #include #include namespace AMDiS { namespace Recursive { template struct ForEach; /// \brief Recursive application of a functor f to a hierarchic container of containers. /** * This utility function applies the given functor f to the "leaf" entries in * a hierarchic container. Therefore, the container is traversed recursively, * using specializations of the ForEach::apply class method. * If no specialization is provided, the function is applied to the whole container * or leaf entry, respectively. **/ template void forEach (Container&& container, F&& f) { ForEach::impl(container,f); } // specializations for container types template struct ForEach { private: // ranges with dynamic index access template ())), class = decltype(std::end(std::declval()))> static void impl2 (Dune::PriorityTag<2>, Vec&& vec, F&& f) { for (auto&& v : vec) Recursive::forEach(v, f); } // ranges with static index access template (std::declval()))> static void impl2 (Dune::PriorityTag<1>, Vec&& vec, F&& f) { Ranges::forEach(vec, [&](auto&& v) { Recursive::forEach(v, f); }); } // no range template static void impl2 (Dune::PriorityTag<0>, Value&& value, F&& f) { f(value); } public: template static void impl (Vec&& vec, F&& f) { impl2(Dune::PriorityTag<5>{}, vec, f); } }; }} // end namespace AMDiS::Recursive
 #pragma once #include #include #include #include #include #include #include namespace AMDiS { namespace Recursive { template struct InnerProduct; /// \brief Recursive inner product of two containers [in1] and [in2] following the signature /// of std::inner_product but applied to the leaf elements of the possibly hierarchic containers template T innerProduct (In1 const& in1, In2 const& in2, T init, BinaryOperation1 op1, BinaryOperation2 op2) { return InnerProduct::impl(in1, in2, std::move(init), op1, op2); } template T innerProduct (In1 const& in1, In2 const& in2, T init) { return InnerProduct::impl(in1, in2, std::move(init), std::plus<>{}, std::multiplies<>{}); } /// General implementation of recursive inner-product template struct InnerProduct { private: // dynamic ranges template ())), class = decltype(std::end(std::declval())), class = decltype(std::begin(std::declval()))> static T impl2 (Dune::PriorityTag<2>, In1 const& in1, In2 const& in2, T init, BinOp1 op1, BinOp2 op2) { auto first1 = std::begin(in1); auto first2 = std::begin(in2); for (; first1 != std::end(in1); ++first1, ++first2) init = Recursive::innerProduct(*first1, *first2, std::move(init), op1, op2); return init; } // ranges with static index access template ()[std::integral_constant{}])> static T impl2 (Dune::PriorityTag<1>, In1 const& in1, In2 const& in2, T init, BinOp1 op1, BinOp2 op2) { static_assert(static_size_v == static_size_v); Ranges::forIndices>([&](auto ii) { init = Recursive::innerProduct(in1[ii], in2[ii], std::move(init), op1, op2); }); return init; } // no range template static T impl2 (Dune::PriorityTag<0>, In1 const& in1, In2 const& in2, T init, BinOp1 op1, BinOp2 op2) { return op1(std::move(init), op2(in1, in2)); } public: template static T impl (In1 const& in1, In2 const& in2, T init, BinOp1 op1, BinOp2 op2) { return impl2(Dune::PriorityTag<5>{}, in1, in2, init, op1, op2); } }; }} // end namespace AMDiS::Recursive
 #pragma once #include #include #include #include #include #include namespace AMDiS { namespace Recursive { template struct Transform; /// \brief Recursive application of a functor op to a hierarchic container of containers. /** * This utility function applies the given functor op to the "leaf" entries in * hierarchic containers {in...} and assigns the output to the hierarchic container [out]. * Therefore, the containers are traversed recursively, using specializations of the * Transform::impl class method. If no such specialization is provided, the function * is applied to the whole containers or leaf entries, respectively. **/ template void transform (Out& out, Op&& op, In const&... in) { Transform>::impl(out,op,in...); } template struct Transform { private: // ranges with dynamic index access template static void impl3 (OutIter d_first, OutIter d_last, Op&& op, InIter... first) { while (d_first != d_last) Recursive::transform(*d_first++, op, *first++...); } // ranges with dynamic index access template ())), class = decltype(std::end(std::declval())), class = std::void_t()))...>> static void impl2 (Dune::PriorityTag<3>, Out& out, Op&& op, In const&... in) { impl3(std::begin(out), std::end(out), op, std::begin(in)...); } // ranges with static index access template ()[std::integral_constant{}])> static void impl2 (Dune::PriorityTag<2>, Out& out, Op&& op, In const&... in) { Ranges::forIndices>([&](auto ii) { Recursive::transform(out[ii], op, in[ii]...); }); } // ranges with static getter access template (std::declval()))> static void impl2 (Dune::PriorityTag<1>, Out& out, Op&& op, In const&... in) { Ranges::forIndices>([&](auto ii) { Recursive::transform(std::get(out), op, std::get(in)...); }); } // no range template static void impl2 (Dune::PriorityTag<0>, Out& out, Op&& op, In const&... in) { out = op(in...); } public: template static void impl (Out& out, Op&& op, In const&... in) { impl2(Dune::PriorityTag<5>{}, out, op, in...); } }; }} // end namespace AMDiS::Recursive
 ... ... @@ -25,8 +25,6 @@ install(FILES Order.hpp QuadMath.hpp Range.hpp RecursiveApply.hpp RecursiveForEach.hpp SharedPtr.hpp StaticSize.hpp String.hpp ... ...
 ... ... @@ -22,7 +22,8 @@ namespace AMDiS (f(get(tuple)),...); } template template (std::declval()))> constexpr void forEach(Tuple&& tuple, Functor&& f) { Ranges::forEach(std::make_index_sequence>{}, FWD(tuple), FWD(f)); ... ...
 #pragma once #include #include #include #include #include namespace AMDiS { namespace Recursive { /// Default implementation of the recursive \ref map function. template struct Apply { template static auto impl(F&& f, T const& t) { return f(t); } }; /// \brief Recursive application of a transformation functor f to a hierarchic /// container of containers, returning the transformed container. /** * This utility function applies the given functor f to the "leaf" entries in * a hierarchic container that returns a transformed container. Therefore, the * container is traversed recursively, using specializations of the Map::apply * class method. If no specialization is provided, the function is applied to the * whole container or leaf entry, respectively. **/ template auto apply(F&& f, T const& t) { return Apply::impl(f,t); } // specializations for container types template struct Apply> { template static auto impl(F&& f, std::array const& a) { return Ranges::applyIndices([&](auto... ii) { return std::array{Recursive::apply(f,a[ii])...}; }); } }; template struct Apply> { template static auto impl(F&& f, std::tuple const& t) { return Ranges::apply([&](auto const&... ti) { return std::tuple{Recursive::apply(f,ti)...}; }, t); } }; template struct Apply> { template static auto impl(F&& f, std::pair const& t) { return std::pair{Recursive::apply(f,t.first), Recursive::apply(f,t.second)}; } }; template struct Apply> { template static auto impl(F&& f, Dune::TupleVector const& t) { return Ranges::apply([&](auto const&... ti) { return Dune::makeTupleVector(Recursive::apply(f,ti)...); }, t); } }; template struct Apply> { template static auto impl(F&& f, std::vector const& v) { using U = TYPEOF(Recursive::apply(f,std::declval())); std::vector out; out.reserve(v.size()); for (std::size_t i = 0; i < v.size(); ++i) out.emplace_back(Recursive::apply(f,v[i])); return out; } }; } // end namespace Recursive } // end namespace AMDiS \ No newline at end of file
 #pragma once #include #include #include #include #include #include #include namespace AMDiS { namespace Recursive { /// Default implementation of the recursive \ref forEach function. /** * \tparam V The type of the container/value decayed to the raw type **/ template struct ForEach { template static void impl(Value&& v, F&& f) { f(v); } }; /// \brief Recursive application of a functor f to a hierarchic container of containers. /** * This utility function applies the given functor f to the "leaf" entries in * a hierarchic container. Therefore, the container is traversed recursively, * using specializations of the ForEach::apply class method. * If no specialization is provided, the function is applied to the whole container * or leaf entry, respectively. **/ template void forEach(Container&& container, F&& f) { ForEach::impl(container,f); } // specializations for container types template struct ForEach> { using indices = std::make_index_sequence; template static void impl2(std::index_sequence, Tuple&& tuple, F&& f) { using std::get; (Recursive::forEach(get(tuple), f),...); } template static void impl(Tuple&& tuple, F&& f) { impl2(indices{}, tuple, f); } }; template struct ForEach> { template static void impl(Pair&& pair, F&& f) { Recursive::forEach(pair.first, f); Recursive::forEach(pair.second, f); } }; template struct ForEach> { template static void impl(Tuple&& tuple, F&& f) { ForEach>::impl(tuple, f); } }; template struct ForEach> { template static void impl(Array&& a, F&& f) { for (auto&& ai : a) Recursive::forEach(ai, f); } }; template struct ForEach> { template static void impl(Vector&& v, F&& f) { for (auto&& vi : v) Recursive::forEach(vi, f); } }; } // end namespace Recursive } // end namespace AMDiS
 ... ... @@ -4,6 +4,7 @@ #include #include #include #include #include ... ... @@ -44,10 +45,10 @@ void DiscreteFunction::