DUNE-FEM (unstable)

hybrid.hh
1#ifndef DUNE_FEM_COMMON_HYBRID_HH
2#define DUNE_FEM_COMMON_HYBRID_HH
3
4#include <cstddef>
5
6#include <tuple>
7#include <type_traits>
8#include <utility>
9
10#include <dune/common/hybridutilities.hh>
12
13#include <dune/fem/common/utility.hh>
14
15namespace Dune
16{
17
18 namespace Hybrid
19 {
20
21 namespace Impl
22 {
23
24 template< class Range, class = void >
25 struct Index;
26
27 template< class T, T... i >
28 struct Index< std::integer_sequence< T, i... > >
29 {
30 typedef T Type;
31 };
32
33 template< class Range >
34 struct Index< Range, void_t< typename Range::Index > >
35 {
36 typedef typename Range::Index Type;
37 };
38
39
40 template< class Index, class = void >
41 struct FlatIndex;
42
43 template< class Index >
44 struct FlatIndex< Index, std::enable_if_t< std::is_integral< Index >::value > >
45 {
46 typedef Index Type;
47 };
48
49 template< class T, T value >
50 struct FlatIndex< std::integral_constant< T, value >, void >
51 {
52 typedef T Type;
53 };
54
55 template< class Index >
56 struct FlatIndex< Index, void_t< typename Index::FlatIndex > >
57 {
58 typedef typename Index::FlatIndex Type;
59 };
60
61 } // namespace Impl
62
63
64
65 // IndexType
66 // ---------
67
68 template< class Range >
69 using IndexType = typename Impl::Index< Range >::Type;
70
71
72
73 // FlatIndexType
74 // -------------
75
76 template< class Index >
77 using FlatIndexType = typename Impl::FlatIndex< Index >::Type;
78
79
80
81 // IndexRange
82 // ----------
83
84 template< class T, T sz >
85 struct IndexRange
86 {
87 typedef T Index;
88
89 static constexpr Index size () { return sz; }
90 };
91
92
93
94 // CompositeIndexRange
95 // -------------------
96
97 template< class... SR >
98 struct CompositeIndexRange
99 {
100 typedef std::common_type_t< IndexType< SR >... > Index;
101
102 template< std::size_t i >
103 using SubRange = std::tuple_element_t< i, std::tuple< SR... > >;
104
105 template< std::size_t i >
106 static constexpr Index offset ( std::integral_constant< std::size_t, i > = {} )
107 {
108 return size( std::make_index_sequence< i >() );
109 }
110
111 static constexpr Index size () { return size( std::index_sequence_for< SR... >() ); }
112
113 private:
114 static constexpr Index size ( std::index_sequence<> ) { return 0; }
115
116 template< std::size_t... i >
117 static constexpr Index size ( std::index_sequence< i... > )
118 {
119 return Std::sum( Hybrid::size( SubRange< i >() )... );
120 }
121 };
122
123
124
125 // forEach for IndexRange
126 // ----------------------
127
128 template< class T, T sz, class F >
129 inline static void forEach ( IndexRange< T, sz > range, F &&f )
130 {
131 for( T i = 0; i < sz; ++i )
132 f( i );
133 }
134
135
136
137 // CompositeIndex
138 // --------------
139
140 template< std::size_t component, class I, I offset, class SI >
141 struct CompositeIndex
142 {
143 typedef I FlatIndex;
144 typedef SI SubIndex;
145
146 private:
147 static constexpr std::integral_constant< std::size_t, component > access ( SubIndex subIndex, std::integral_constant< std::size_t, 0 > ) { return {}; }
148
149 static constexpr FlatIndexType< SubIndex > access ( FlatIndexType< SubIndex > subIndex, std::integral_constant< std::size_t, 1 > ) { return subIndex; }
150
151 template< std::size_t _component, class _I, _I _offset, class _SI, std::size_t i >
152 static constexpr decltype( auto ) access ( CompositeIndex< _component, _I, _offset, _SI > subIndex, std::integral_constant< std::size_t, i > )
153 {
154 return subIndex[ std::integral_constant< std::size_t, i-1 >() ];
155 }
156
157 template< std::size_t i >
158 using Access = decltype( access( std::declval< SubIndex >(), std::integral_constant< std::size_t, i >() ) );
159
160 public:
161 explicit constexpr CompositeIndex ( SubIndex subIndex ) : subIndex_( std::move( subIndex ) ) {}
162
163 constexpr operator I () const { return (offset + static_cast< FlatIndexType< SubIndex > >( subIndex() )); }
164
165 template< std::size_t i >
166 constexpr auto operator[] ( std::integral_constant< std::size_t, i > ) const
167 -> std::enable_if_t< !IsIntegralConstant< Access< i > >::value, Access< i > >
168 {
169 return access( subIndex(), std::integral_constant< std::size_t, i >() );
170 }
171
172 template< std::size_t i >
173 constexpr auto operator[] ( std::integral_constant< std::size_t, i > ) const
174 -> std::enable_if_t< IsIntegralConstant< Access< i > >::value, std::decay_t< Access< i > > >
175 {
176 return {};
177 }
178
179 const SubIndex &subIndex () const { return subIndex_; }
180
181 private:
182 SubIndex subIndex_;
183 };
184
185
186
187 // forEach for CompositeIndexRange
188 // -------------------------------
189
190 template< class... SR, class F >
191 inline static void forEach ( CompositeIndexRange< SR... >, F &&f );
192
193 namespace Impl
194 {
195
196 template< class Range, class F >
197 struct CompositeIndexRangeInnerLoop
198 {
199 explicit CompositeIndexRangeInnerLoop ( F f )
200 : f_( std::move( f ) )
201 {}
202
203 template< std::size_t component >
204 void operator() ( std::integral_constant< std::size_t, component > )
205 {
206 typedef IndexType< Range > Index;
207 typedef typename Range::template SubRange< component > SubRange;
208
209 Hybrid::forEach( SubRange(), [ this ] ( auto subIndex ) {
210 f_( CompositeIndex< component, Index, Range::template offset< component >(), std::decay_t< decltype( subIndex ) > >( std::move( subIndex ) ) );
211 } );
212 }
213
214 private:
215 F f_;
216 };
217
218 } // namespace Impl
219
220 template< class... SR, class F >
221 inline static void forEach ( CompositeIndexRange< SR... >, F &&f )
222 {
223 Impl::CompositeIndexRangeInnerLoop< CompositeIndexRange< SR... >, F > innerLoop( std::forward< F >( f ) );
224 forEach( std::index_sequence_for< SR... >(), innerLoop );
225 }
226
227 } // namespace Hybrid
228
229} // namespace Dune
230
231#endif // #ifndef DUNE_FEM_COMMON_HYBRID_HH
typename Impl::voider< Types... >::type void_t
Is void for all valid input types. The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:40
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
STL namespace.
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)