1#ifndef DUNE_FEM_COMMON_HYBRID_HH
2#define DUNE_FEM_COMMON_HYBRID_HH
10#include <dune/common/hybridutilities.hh>
13#include <dune/fem/common/utility.hh>
24 template<
class Range,
class =
void >
27 template<
class T, T... i >
28 struct Index<
std::integer_sequence< T, i... > >
33 template<
class Range >
34 struct Index< Range,
void_t< typename Range::Index > >
36 typedef typename Range::Index Type;
40 template<
class Index,
class =
void >
43 template<
class Index >
44 struct FlatIndex< Index,
std::enable_if_t< std::is_integral< Index >::value > >
49 template<
class T, T value >
50 struct FlatIndex<
std::integral_constant< T, value >, void >
55 template<
class Index >
56 struct FlatIndex< Index,
void_t< typename Index::FlatIndex > >
58 typedef typename Index::FlatIndex Type;
68 template<
class Range >
69 using IndexType =
typename Impl::Index< Range >::Type;
76 template<
class Index >
77 using FlatIndexType =
typename Impl::FlatIndex< Index >::Type;
84 template<
class T, T sz >
89 static constexpr Index
size () {
return sz; }
97 template<
class... SR >
98 struct CompositeIndexRange
100 typedef std::common_type_t< IndexType< SR >... > Index;
102 template< std::
size_t i >
103 using SubRange = std::tuple_element_t< i, std::tuple< SR... > >;
105 template< std::
size_t i >
106 static constexpr Index offset ( std::integral_constant< std::size_t, i > = {} )
108 return size( std::make_index_sequence< i >() );
111 static constexpr Index
size () {
return size( std::index_sequence_for< SR... >() ); }
114 static constexpr Index
size ( std::index_sequence<> ) {
return 0; }
116 template< std::size_t... i >
117 static constexpr Index
size ( std::index_sequence< i... > )
119 return Std::sum( Hybrid::size( SubRange< i >() )... );
128 template<
class T, T sz,
class F >
129 inline static void forEach ( IndexRange< T, sz > range, F &&f )
131 for( T i = 0; i < sz; ++i )
140 template< std::
size_t component,
class I, I offset,
class SI >
141 struct CompositeIndex
147 static constexpr std::integral_constant< std::size_t, component > access ( SubIndex subIndex, std::integral_constant< std::size_t, 0 > ) {
return {}; }
149 static constexpr FlatIndexType< SubIndex > access ( FlatIndexType< SubIndex > subIndex, std::integral_constant< std::size_t, 1 > ) {
return subIndex; }
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 > )
154 return subIndex[ std::integral_constant< std::size_t, i-1 >() ];
157 template< std::
size_t i >
158 using Access =
decltype( access( std::declval< SubIndex >(), std::integral_constant< std::size_t, i >() ) );
161 explicit constexpr CompositeIndex ( SubIndex subIndex ) : subIndex_(
std::move( subIndex ) ) {}
163 constexpr operator I ()
const {
return (offset +
static_cast< FlatIndexType< SubIndex >
>( subIndex() )); }
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 > >
169 return access( subIndex(), std::integral_constant< std::size_t, i >() );
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 > > >
179 const SubIndex &subIndex ()
const {
return subIndex_; }
190 template<
class... SR,
class F >
191 inline static void forEach ( CompositeIndexRange< SR... >, F &&f );
196 template<
class Range,
class F >
197 struct CompositeIndexRangeInnerLoop
199 explicit CompositeIndexRangeInnerLoop ( F f )
200 : f_(
std::move( f ) )
203 template< std::
size_t component >
204 void operator() ( std::integral_constant< std::size_t, component > )
206 typedef IndexType< Range > Index;
207 typedef typename Range::template SubRange< component > SubRange;
210 f_( CompositeIndex< component, Index, Range::template offset< component >(), std::decay_t<
decltype( subIndex ) > >( std::move( subIndex ) ) );
220 template<
class... SR,
class F >
221 inline static void forEach ( CompositeIndexRange< SR... >, F &&f )
223 Impl::CompositeIndexRangeInnerLoop< CompositeIndexRange< SR... >, F > innerLoop( std::forward< F >( f ) );
224 forEach( std::index_sequence_for< SR... >(), innerLoop );
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
Traits for type conversions and type information.