NiHu  2.0
fmm_operator_collection.hpp
Go to the documentation of this file.
1 
7 #ifndef FMM_OPERATOR_COLLECTION_HPP_INCLUDED
8 #define FMM_OPERATOR_COLLECTION_HPP_INCLUDED
9 
10 #include <type_traits>
11 #include <tuple>
12 
13 namespace NiHu
14 {
15 namespace fmm
16 {
17 
20 // Forward declaration of class
21 template <class ...Ops>
23 
24 // Forward declaration of creator function
25 template <class ...Ops>
27 create_fmm_operator_collection(Ops &&... ops);
28 
37 template <class ...Ops>
39 {
40 private:
41  template <class FmmTag, class First, class...Tail>
42  struct op_type_impl : std::conditional<
43  std::is_same<typename std::decay<First>::type::fmm_tag, FmmTag>::value,
44  First,
45  typename op_type_impl<FmmTag, Tail...>::type
46  > {};
47 
48  template <class FmmTag, class Last>
49  struct op_type_impl<FmmTag, Last> : std::conditional<
50  std::is_same<typename std::decay<Last>::type::fmm_tag, FmmTag>::value,
51  Last,
52  void
53  > {};
54 
60  fmm_operator_collection(std::tuple<Ops...> && ops)
61  : m_ops(std::forward<std::tuple<Ops...> >(ops))
62  {
63  }
64 
65 public:
73  template <class FmmTag>
74  struct op_type : op_type_impl<FmmTag, Ops...> {};
75 
80  fmm_operator_collection(Ops &&... ops)
81  : m_ops(std::forward<Ops>(ops)...)
82  {
83  }
84 
95  template <typename FmmTag>
96  auto get(FmmTag tag) const
97  {
98  typedef typename op_type<FmmTag>::type operator_t;
99 
100  // The required operator type must be present
101  static_assert(!std::is_same<operator_t, void>::value,
102  "The required operator type was not found in the collection");
103 
104  return std::get<operator_t>(m_ops);
105  }
106 
112  template <class ...OpsRhs>
114  {
115  return fmm_operator_collection(std::tuple_cat(m_ops, rhs.m_ops));
116  }
117 
123  template <class Operator>
124  auto operator|(Operator &&rhs) const
125  {
126  return this->operator|(create_fmm_operator_collection(std::forward<Operator>(rhs)));
127  }
128 
129 private:
136  template <class F, size_t... Is>
137  auto transform_impl(F f, std::index_sequence<Is...>) {
139  f(std::get<Is>(m_ops))...
140  );
141  }
142 
143 public:
150  template <class F>
151  auto transform(F f) {
152  return transform_impl(
153  f, std::make_index_sequence<sizeof...(Ops)>{});
154  }
155 
156 private:
158  std::tuple<Ops...> m_ops;
159 };
160 
164 template <class ...Ops>
165 fmm_operator_collection<Ops...>
167 {
168  return fmm_operator_collection<Ops...>(std::forward<Ops>(ops)...);
169 }
170 
171 } // end of namespace fmm
172 } // end of namespace NiHu
173 
174 template <class Operator, class ...OpsColl>
175 auto operator|(Operator &&op, NiHu::fmm::fmm_operator_collection<OpsColl...> &&coll)
176 {
177  return std::forward<NiHu::fmm::fmm_operator_collection<OpsColl...> >(coll) | std::forward<Operator>(op);
178 }
179 
180 
181 #endif /* FMM_OPERATOR_COLLECTION_HPP_INCLUDED */
NiHu::fmm::fmm_operator_collection::operator|
auto operator|(Operator &&rhs) const
Concatenate (create union of) a collection and an operator.
Definition: fmm_operator_collection.hpp:124
NiHu::fmm::fmm_operator_collection::operator|
auto operator|(fmm_operator_collection< OpsRhs... > &&rhs) const
Concatenate (create union of) two operator collections.
Definition: fmm_operator_collection.hpp:113
NiHu::fmm::fmm_operator_collection::get
auto get(FmmTag tag) const
Retrieve operator from the collection.
Definition: fmm_operator_collection.hpp:96
NiHu::fmm::fmm_operator_collection::fmm_operator_collection
fmm_operator_collection(Ops &&... ops)
Constructor.
Definition: fmm_operator_collection.hpp:80
NiHu::fmm::fmm_operator_collection::op_type
Metafunction for retreiving operator type for a given tag.
Definition: fmm_operator_collection.hpp:74
NiHu::fmm::fmm_operator_collection::transform
auto transform(F f)
Transform collection.
Definition: fmm_operator_collection.hpp:151
NiHu::fmm::create_fmm_operator_collection
fmm_operator_collection< Ops... > create_fmm_operator_collection(Ops &&... ops)
Create function for the collection.
Definition: fmm_operator_collection.hpp:166
NiHu::fmm::fmm_operator_collection
Class representing a collection of FMM operators.
Definition: fmm_operator_collection.hpp:22