dune-functions  2.5-dev
indexaccess.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_FUNCTIONS_COMMON_INDEX_ACCESS_HH
4 #define DUNE_FUNCTIONS_COMMON_INDEX_ACCESS_HH
5 
6 
7 #include <dune/common/concept.hh>
8 #include <dune/common/hybridutilities.hh>
9 
10 
11 
12 namespace Dune {
13 namespace Functions {
14 
15 
16 namespace Imp {
17 
18 namespace Concept {
19 template<class size_type>
21 {
22  template<class C>
23  auto require(C&& c) -> decltype(
24  c[std::declval<size_type>()]
25  );
26 };
27 
28 } // namespace Concept
29 
30 } // namespace Imp
31 
32 
33 
46 template<class C, class I, class F,
47  typename std::enable_if< Dune::models<Imp::Concept::HasDynamicIndexAccess<I>, C>(), int>::type = 0>
48 auto hybridIndexAccess(C&& c, const I& i, F&& f)
49  -> decltype(f(c[i]))
50 {
51  return f(c[i]);
52 }
53 
71 template<class C, class I, class F,
72  typename std::enable_if< not Dune::models<Imp::Concept::HasDynamicIndexAccess<I>, C>(), int>::type = 0>
73 decltype(auto) hybridIndexAccess(C&& c, const I& i, F&& f)
74 {
75  using Size = decltype(Hybrid::size(c));
76  return Hybrid::switchCases(std::make_index_sequence<Size::value>(), i,
77  [&](const auto& ii) -> decltype(auto){
78  return f(c[ii]);
79  }, [&]() -> decltype(auto){
80  return f(c[Dune::Indices::_0]);
81  });
82 }
83 
84 
85 
99 template<class Index, std::size_t offset=1>
101 {
102 public:
103  ShiftedMultiIndex(const Index& index) :
104  index_(index)
105  {}
106 
107  template<class P>
108  decltype(auto) operator[](const P& position) const
109  {
110  return index_[position+offset];
111  }
112 
117  {
118  return {index_};
119  }
120 
121  auto size() const
122  {
123  return index_.size() - offset;
124  }
125 
126 private:
127  const Index& index_;
128 };
129 
130 
131 
137 template<std::size_t offset, class Index>
139 {
140  return {index};
141 }
142 
143 
144 
150 template<class Index>
152 {
153  return {index};
154 }
155 
156 
157 
158 namespace Imp {
159 
160 template<class Result, class Index>
162 {
163  MultiIndexResolver(const Index& index) :
164  index_(index)
165  {}
166 
167  template<class C,
168  typename std::enable_if<not std::is_convertible<C&, Result>::value, int>::type = 0>
169  Result operator()(C&& c)
170  {
171  auto&& subIndex = shiftedMultiIndex(index_);
172  auto&& subIndexResolver = MultiIndexResolver<Result, decltype(subIndex)>(subIndex);
173  return (Result)(hybridIndexAccess(c, index_[Dune::Indices::_0], subIndexResolver));
174  }
175 
176  template<class C,
177  typename std::enable_if<std::is_convertible<C&, Result>::value, int>::type = 0>
178  Result operator()(C&& c)
179  {
180  return (Result)(std::forward<C>(c));
181  }
182 
183  const Index& index_;
184 };
185 
186 } // namespace Imp
187 
188 
189 
208 template<class Result, class C, class MultiIndex>
209 Result hybridMultiIndexAccess(C&& c, const MultiIndex& index)
210 {
211 
212  Imp::MultiIndexResolver<Result, MultiIndex> multiIndexResolver(index);
213  return multiIndexResolver(c);
214 }
215 
216 
217 
218 } // namespace Dune::Functions
219 } // namespace Dune
220 
221 
222 
223 #endif // DUNE_FUNCTIONS_COMMON_INDEX_ACCESS_HH
const Index & index_
Definition: indexaccess.hh:183
auto size() const
Definition: indexaccess.hh:121
auto hybridIndexAccess(C &&c, const I &i, F &&f) -> decltype(f(c[i]))
Provide operator[] index-access for containers.
Definition: indexaccess.hh:48
Definition: polynomial.hh:7
Definition: indexaccess.hh:161
MultiIndexResolver(const Index &index)
Definition: indexaccess.hh:163
Result hybridMultiIndexAccess(C &&c, const MultiIndex &index)
Provide multi-index access by chaining operator[].
Definition: indexaccess.hh:209
ShiftedMultiIndex(const Index &index)
Definition: indexaccess.hh:103
ShiftedMultiIndex< Index, offset > shiftedMultiIndex(const Index &index)
Create a ShiftedMultiIndex.
Definition: indexaccess.hh:138
Result operator()(C &&c)
Definition: indexaccess.hh:169
auto require(C &&c) -> decltype(c[std::declval< size_type >()])
ShiftedMultiIndex< Index, offset+1 > pop() const
Return multi index with one more position truncated.
Definition: indexaccess.hh:116
Class representing a shifted multi index.
Definition: indexaccess.hh:100