SUNphi  1.0
Indexer.hpp
Go to the documentation of this file.
1 #ifndef _INDEXER_HPP
2 #define _INDEXER_HPP
3 
4 /// \file Indexer.hpp
5 ///
6 /// \brief Header file for the definition of an indexer
7 
8 #ifdef HAVE_CONFIG_H
9  #include <config.hpp>
10 #endif
11 
12 #include <metaprogramming/TypeTraits.hpp>
13 #include <system/Memory.hpp>
14 #include <tens/TensKind.hpp>
15 
16 namespace SUNphi
17 {
18  /// Indexer class to compute an index for a TensKind
19  ///
20  /// Forward declaration
21  template <int IDyn, // Index of the current dynamic component
22  class T, // Generic type
23  class=FalseType> // Forbids instantiation
25  {
26  };
27 
28  /// Indexer class to compute an index for a TensKind
29  ///
30  /// Recursive implementation definining a nested indexer and
31  /// calling it until no component is found. The check on types is
32  /// done in the externally visible routine.
33  template <int IDyn, // Index of the current dynamic component in the list
34  class H, // Current TensKind
35  class...Oth> // Other TensKind
36  struct _Indexer<IDyn,TensKind<H,Oth...>>
37  {
38  /// Size of the top-level class
39  static constexpr int headSize=
40  H::size;
41 
42  /// Check if this component is dynamic
43  static constexpr bool thisDynamic=
44  (headSize==DYNAMIC);
45 
46  /// Nested TensKind
47  using NestedTk=
49 
50  /// Nested Dynamic index
51  static constexpr int nestedIDyn=
52  (thisDynamic ? IDyn+1 : IDyn);
53 
54  /// Nested indexer
55  using Nested=
57 
58  /// Compute the index, given a set of components
59  ///
60  /// Internal implementation
61  /// \todo fix the int types
62  template <size_t NTotDyn, // Total number of dynamic components
63  class Head, // Current component type
64  class...Tail, // Other component types
65  class=ConstrainAreIntegrals<Head,Tail...>> // Constrain all types to be integral
66  static constexpr int index(const DynSizes<NTotDyn>& dynSizes, ///< Dynamic sizes
67  const int in, ///< External partial index
68  const Head& head, ///< Current component
69  const Tail&...tail) ///< Other components
70  {
71  // Constrain the components to be in the same number of the type
72  static_assert(sizeof...(Oth)==sizeof...(Tail),"Number of TensComp does not match number of passed components");
73 
74  // Current component
75  const int thisComp=
76  head;
77 
78  // Current size
79  const int size=
81  dynSizes[IDyn]:
82  headSize;
83 
84  // Compute the result
85  int out=thisComp+size*in;
86 
87  // Nested value
88  if constexpr(sizeof...(Tail)>0)
89  {
90 #ifdef DEBUG_INDEXER
91  printf("Is Nested , thiscomp: %d , is Dyn: %d",thisComp,thisDynamic);
92  printf(", HeadSize: %d",headSize);
93  printf(", Size: %d",size);
94  printf(", %d",IDyn);
95  if(thisDynamic) printf(" %d",dynSizes[IDyn]);
96  printf("\n");
97 #endif
98 
99  return Nested::index(forw<const DynSizes<NTotDyn>>(dynSizes),out,forw<const Tail>(tail)...);
100  }
101  else
102  {
103 #ifdef DEBUG_INDEXER
104  std::cout<<"Non-Nested , value: "<<out<<std::endl;
105 #endif
106  return out;
107  }
108  }
109  };
110 
111  /// Index function for a TensKind
112  ///
113  /// Wraps the call to the Indexer class method
114  /// The index is built in this way.
115  /// Let us assume three component case
116  ///
117  /// \code
118  /// a+Na*(b+Nb*c)
119  /// \endcode
120  ///
121  /// this is changed into a more homogeneous
122  ///
123  /// \code
124  /// a+Na*(b+Nb*(c+Nc*0))
125  /// \endcode
126  ///
127  /// so that every component needs to perform the following operation
128  ///
129  /// \code
130  /// i+N*ext
131  /// \endcode
132  ///
133  /// where \c ext is the result of the calculation for the outer
134  /// component. Starting from 0, the calculation ends when no more
135  /// component is present (terminating case).
136  template <class TK, // Tensor Kind
137  size_t NDynamic, // Number of dynamic components
138  class...Args> // Types of the components
139  static constexpr int index(const DynSizes<NDynamic>& dynSizes, ///< Sizes of the dynamical components
140  const Args&...args) ///< Components index
141  {
142  static_assert(TK::nDynamic==NDynamic,"Nuber of dynamic components sizes must agree with the TensKind one");
144 
145 #ifdef DEBUG_INDEXER
146  print(std::cout,"Components:",args...,"\n");
147 #endif
148 
149  return _Indexer<0,TK>::index(dynSizes,0,args...);
150  }
151 }
152 
153 #endif
#define STATIC_ASSERT_ARE_INTEGRALS(...)
Static assert if the types T are not an integer-like.
Definition: TypeTraits.hpp:484
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87