ForEach.hpp 1.81 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once

#include <array>
#include <tuple>
#include <vector>
#include <type_traits>
#include <utility>

#include <dune/common/tuplevector.hh>
#include <amdis/common/ForEach.hpp>
#include <amdis/common/TypeTraits.hpp>

namespace AMDiS {
namespace Recursive {

template <class Vec>
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,
23
 * using specializations of the `ForEach<Container>::impl` class method.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 * If no specialization is provided, the function is applied to the whole container
 * or leaf entry, respectively.
 **/
template <class Container, class F>
void forEach (Container&& container, F&& f)
{
  ForEach<TYPEOF(container)>::impl(container,f);
}


// specializations for container types


template <class>
struct ForEach
{
private:
  // ranges with dynamic index access
  template <class Vec, class F,
    class = decltype(std::begin(std::declval<Vec>())),
    class = decltype(std::end(std::declval<Vec>()))>
  static void impl2 (Dune::PriorityTag<2>, Vec&& vec, F&& f)
  {
    for (auto&& v : vec)
      Recursive::forEach(v, f);
  }

  // ranges with static index access
  template <class Vec, class F,
    class = decltype(std::get<0>(std::declval<Vec>()))>
  static void impl2 (Dune::PriorityTag<1>, Vec&& vec, F&& f)
  {
    Ranges::forEach(vec, [&](auto&& v) {
      Recursive::forEach(v, f);
    });
  }

  // no range
  template <class Value, class F>
  static void impl2 (Dune::PriorityTag<0>, Value&& value, F&& f)
  {
    f(value);
  }

public:
  template <class Vec, class F>
  static void impl (Vec&& vec, F&& f)
  {
    impl2(Dune::PriorityTag<5>{}, vec, f);
  }
};

}} // end namespace AMDiS::Recursive