SUNphi  1.0
IntSeqGetEl.hpp
Go to the documentation of this file.
1 #ifndef _INTSEQGETEL_HPP
2 #define _INTSEQGETEL_HPP
3 
4 #include <ints/IntSeqCat.hpp>
5 #include <utility/Position.hpp>
6 
7 /// \file IntSeqGetEl.hpp
8 ///
9 /// \brief Gets element from an \c IntSeq according to specific pattern
10 
11 namespace SUNphi
12 {
13  /// Returns all the \c IntSeq but the first N elements
14  ///
15  /// Recursive internal implementation
16  template <int N, // Number of elements to disregard
17  int Head, // First element
18  int...Tail> // All the other elements
19  DECLAUTO _IntSeqGetAllButFirstN(IntSeq<Head,Tail...>)
20  {
21  static_assert(N>=0 and N<=sizeof...(Tail)+1,"N must be in the range [0,size)");
22 
23  if constexpr(N==0)
24  return IntSeq<Head,Tail...>{};
25  else
26  if constexpr(N==1)
27  return IntSeq<Tail...>{};
28  else
29  return _IntSeqGetAllButFirstN<N-1>(IntSeq<Tail...>{});
30  }
31 
32  /// Returns all the \c IntSeq but the first N elements
33  ///
34  /// Gives visibility to the internal implementation
35  template <int N, // Number of elements to disregard
36  typename Is> // \c IntSeq to filter
37  using IntSeqGetAllButFirstN=
38  decltype(_IntSeqGetAllButFirstN<N>(Is{}));
39 
40  /// Returns all the \c IntSeq but the first element
41  template <typename Is> // \c IntSeq to filter
42  using IntSeqGetAllButFirst=
43  IntSeqGetAllButFirstN<1,Is>;
44 
45  /// Modified extraction of an element in an \c IntSeq after appending a value
46  ///
47  /// Returns an \c IntSeq containing the element of position \c Pos
48  /// in the passed \c IntSeq, after appending a given value to it. If
49  /// asked, the returned \c NOT_PRESENT is replaced with empty value.
50  ///
51  /// \code
52  ///
53  /// int a=
54  /// posInIntSeqAfterAppending<2,4>(IntSeq<0,1,2,3){}>; // 2
55  ///
56  /// \endcode
57  template <int Tail, // Tail to be added before extracting
58  bool ReturnNotPresent, // Switch either returning \c NOT PRESENT or \c void, if not found
59  int Pos, // Position to extract
60  int...Head> // Integers from which to extract
61  constexpr DECLAUTO _IntSeqGetElAfterAppending(IntSeq<Head...>)
62  {
63  /// Full \c IntSeq to be searched
64  using Is=
65  IntSeq<Head...,Tail>;
66 
67  /// Element search return
68  constexpr int P=
69  Is::template element<Pos>();
70 
71  // If the position is not present return empty, or \c NOT_PRESENT
72  if constexpr(P==NOT_PRESENT and not ReturnNotPresent)
73  return IntSeq<>{};
74  else
75  return IntSeq<P>{};
76  }
77 
78  /// Modified extraction of an element in an \c IntSeq after appending a value
79  ///
80  /// Internal implementation
81  template <int Tail, // Tail to be added before extracting
82  bool ReturnNotPresent, // Switch either returning \c NOT PRESENT or \c void, if not found
83  int...Pos, // Positions to extract
84  int...Head> // Integers from which to extract
85  DECLAUTO _IntSeqGetElsAfterAppending(IntSeq<Pos...>,
86  IntSeq<Head...>)
87  {
88  return IntSeqCat<decltype(_IntSeqGetElAfterAppending<Tail,ReturnNotPresent,Pos>(IntSeq<Head...>{}))...>{};
89  }
90 
91  /// Modified extraction of an element in an \c IntSeq after appending a value
92  ///
93  /// Returns an \c IntSeq containing the element of all positions \c
94  /// Pos in the passed \c IntSeq, after appending a given value to
95  /// it. If asked, all the \c NOT_PRESENT are replaced with empty value.
96  template <int Tail, // Tail to be added before extracting
97  bool ReturnNotPresent, // Switch either returning \c NOT PRESENT or \c void, if not found
98  typename Pos, // \c IntSeq containing the positions to extract
99  typename Head> // \c IntSeq containing the integers to extract
100  using IntSeqGetElsAfterAppending=
101  decltype(_IntSeqGetElsAfterAppending<Tail,ReturnNotPresent>(Pos{},Head{}));
102 }
103 
104 #endif
#define DECLAUTO
Short name for decltype(auto)