SUNphi  1.0
IntSeq.hpp
Go to the documentation of this file.
1 #ifndef _INTSEQ_HPP
2 #define _INTSEQ_HPP
3 
4 /// \file IntSeq.hpp
5 ///
6 /// \brief Implements a struct holding a sequence of integers
7 
8 #include <array>
9 
10 #include <ints/IntListOperations.hpp>
11 #include <ints/IntListOrder.hpp>
12 #include <ints/IntListGetEl.hpp>
13 #include <metaprogramming/TypeTraits.hpp>
14 #include <metaprogramming/UniversalReferences.hpp>
15 
16 namespace SUNphi
17 {
18  DEFINE_BASE_TYPE(IntSeq);
19 
20  /// A struct holding a sequence of integer (similar to stdlib).
21  ///
22  /// The \c integers are held as parameters of the class. To
23  /// intercept them, use the class in a consmett in which the integer
24  /// list are deduced as template parameter, as in this example:
25  ///
26  /// \code
27  /// template <class T>
28  /// class PutIntoArrays
29  /// {
30  /// };
31  ///
32  /// template <int...Ints>
33  /// class PutIntoArrays<IntSeq<Ints...>>
34  /// {
35  /// std::array<int,IntSeq<Ints...>::Size> arr{{Ints...}};
36  /// };
37  /// \endcode
38  ///
39  /// \tparam Ints the list of integer
40  template <int...Ints>
41  struct IntSeq :
42  public BaseIntSeq
43  {
44  /// Length of the sequence of integer
45  static constexpr int size=
46  sizeof...(Ints);
47 
48  /// Returns a constexpr array containing the \c Ints
49  static constexpr std::array<int,size> array{Ints...};
50 
51  /// Sum of all elements
52  static constexpr int hSum=
53  SUNphi::hSum<Ints...>;
54 
55  /// Sum of all elements
56  template <int I>
57  static constexpr int hSumFirst=
58  SUNphi::hSumFirst<I,Ints...>;
59 
60  /// Take first position wher I does not occur
61  template <int I>
62  static constexpr int firstNon=
63  SUNphi::firstNon<I,Ints...>;
64 
65  /// Product of all elements
66  static constexpr int hMul=
67  SUNphi::hMul<Ints...>;
68 
69  /// Defines a new integer sequence incremented by a constant I
70  template <int I>
71  using Add=
72  IntSeq<(Ints+I)...>;
73 
74  /// Defines a new integer sequence decreased by a constant I
75  template <int I>
76  using Sub=
77  Add<-I>;
78 
79  /// Define a new integer sequence inflated by a constant factor I
80  template <int I>
81  using Mul=
82  IntSeq<(Ints*I)...>;
83 
84  /// Define a new integer sequence decreased by a constant factor I
85  template <int I>
86  using Div=
87  TypeIf<I!=0,Mul<1/I>>;
88 
89  /// Returns the maximal element of the list
90  static constexpr int max=
91  SUNphi::maxOfList<Ints...>;
92 
93  /// Get the I element of the sequence
94  template <int I>
95  static constexpr int element()
96  {
97  return getIntOfList<I,Ints...>;
98  }
99 
100  /// Get the first element of the sequence
101  static constexpr int first=
102  element<0>();
103 
104  /// Get the last element of the sequence
105  static constexpr int last=
106  element<size-1>();
107 
108  /// Determine whether the IntSeq elements are ordered or not
109  static constexpr int isOrdered=
110  areOrdered<Ints...>;
111 
112  /// Determine whether the IntSeq elements are ordered and different or not
115 
116  /// Determine whether the elements are contained
117  ///
118  /// Example
119  /// \code
120  /// IntSeq<0,2,2,4>::template has<2>; // true
121  /// IntSeq<0,2,2,4>::template has<4,2>; // true
122  /// IntSeq<0,2,2,4>::template has<5>; // false
123  /// \encode
124  template <int...El>
125  static constexpr bool has=
126  ((firstEq<El,Ints...>!=size) & ...);
127 
128  /// Returns the number of occurrency of El
129  ///
130  /// Example
131  /// \code
132  /// IntSeq<0,2,2,4>::template nOf<2>; // 2
133  /// IntSeq<0,2,2,4>::template nOf<4>; // 1
134  /// IntSeq<0,2,2,4>::template nOf<5>; // 0
135  /// \encode
136  template <int El>
137  static constexpr int nOf=
138  SUNphi::hSum<(Ints==El)...>;
139 
140  /// Checks if an IntSeq is a subset of the current one
141  ///
142  /// Example
143  /// \code
144  /// IntSeq<0,2,2>::template isSubsetOf<IntSeq<0,2,2,4>>; // true
145  /// IntSeq<0,2,2>::template isSubsetOf<IntSeq<0,2,4>>; // false
146  /// \endcode
147  template <typename Is,
148  typename=EnableIf<isIntSeq<Is>>>
149  static constexpr bool isSubsetOf=
150  ((nOf<Ints> ==Is::template nOf<Ints>) & ...);
151 
152  /////////////////////////////////////////////////////////////////
153 
154  /// Append the first N id of another IntSeq
155  ///
156  /// Internal implementation, forward declaration
157  template <bool,
158  int N,
159  typename Right>
160  struct _AppendFirstN;
161 
162  /// Append the first N id of another IntSeq
163  ///
164  /// Internal implementation, taking recursively until N==0
165  template <int N,
166  int HeadR,
167  int...TailR>
168  struct _AppendFirstN<true,N,IntSeq<HeadR,TailR...>>
169  {
170  /// Returned type
171  using type=typename IntSeq<Ints...,HeadR>::template AppendFirstN<N-1,IntSeq<TailR...>>;
172 
173  };
174 
175  /// Append the first N id of another IntSeq
176  ///
177  /// Internal implementation, terminator N==0
178  template <int N,
179  int...R>
180  struct _AppendFirstN<false,N,IntSeq<R...>>
181  {
182  /// Returned type
183  using type=IntSeq<R...>;
184  };
185 
186  /// Append the first N id of another IntSeq
187  ///
188  /// Gives visibility to internal implementation
189  template <int N,
190  typename ISeq>
191  using AppendFirstN=typename _AppendFirstN<(N>0),N,ISeq>::type;
192  };
193 
194  /////////////////////////////////////////////////////////////////
195 
196  /// Create an IntSeq with given types
197  template <int...Ints>
198  [[ maybe_unused ]]
199  constexpr DECLAUTO intSeq=
200  IntSeq<Ints...>{};
201 
202  /////////////////////////////////////////////////////////////////
203 
204  /// Identifies whether a type is an ordered IntSeq
205  ///
206  /// General case
207  template <typename T>
208  [[ maybe_unused ]]
209  constexpr bool isOrderedIntSeq=
210  false;
211 
212  /// Identifies whether a type is an ordered IntSeq
213  ///
214  /// General case
215  template <int...Ints>
216  constexpr bool isOrderedIntSeq<IntSeq<Ints...>> =
217  IntSeq<Ints...>::isOrdered;
218 
219  /// Constrain the IntSeq to be ordered
220  template <typename T,
221  typename=ConstrainIsIntSeq<T>>
222  struct ConstrainIsOrderedIntSeq
223  {
224  /// Internal type
225  using type=T;
226 
227  static_assert(isOrderedIntSeq<T>,"IntSeq is not ordered");
228  };
229 
230  /// Constrain the IntSeq to be ordered and unique
231  template <typename T,
232  typename=ConstrainIsIntSeq<T>>
233  struct ConstrainIsOrderedUniqueIntSeq
234  {
235  /// Internal type
236  using type=T;
237  static_assert(Unqualified<T>::isOrderedUnique,"IntSeq is not ordered and unique");
238  };
239 }
240 
241 #endif
constexpr bool isOrderedIntSeq
Definition: IntSeq.hpp:209
static constexpr std::array< int, size > array
Returns a constexpr array containing the Ints.
Definition: IntSeq.hpp:49
static constexpr int element()
Get the I element of the sequence.
Definition: IntSeq.hpp:95
#define DECLAUTO
Short name for decltype(auto)
#define DEFINE_BASE_TYPE(TYPE,...)
Definition: TypeTraits.hpp:526