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:257
 
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
free standing function for setting up a range based for loop over an integer range for (auto i: range...
Definition: rangeutilities.hh:288
 
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.