SUNphi  1.0
TwinsComp.hpp
Go to the documentation of this file.
1 #ifndef _TWINSCOMP_HPP
2 #define _TWINSCOMP_HPP
3 
4 /// \file TwinsComp.hpp
5 ///
6 /// \brief Header file to define twins TensComp
7 ///
8 /// The twin component of a TensComp is another TensComp. A pair of
9 /// TwinComp is used to distinguish row and column component of
10 /// matrices.
11 
12 #include <ints/IntSeqInsert.hpp>
13 #include <tens/TensComp.hpp>
14 #include <smet/BaseSmET.hpp>
15 #include <tuple/TupleClass.hpp>
16 #include <tuple/TupleOrder.hpp>
17 #include <utility/Unused.hpp>
18 
19 namespace SUNphi
20 {
21  /// Determine if the TensComp has a twin
22  ///
23  /// Default for a generic TensComp: false
24  template <class T, // Type to declare not twinned
25  class=ConstrainIsTensComp<T>> // Constrain the T to be a TensComp
26  [[ maybe_unused ]]
27  constexpr inline bool hasTwin=
28  false;
29 
30  /// Specify the twin component of a given TensComp
31  ///
32  /// Internal implementation for generic case, returning the input
33  template <class T, // Type of which we want to declare the twin
34  class=ConstrainIsTensComp<T>> // Constrain T to be a TensComp
35  struct _TwinCompOf
36  {
37  /// Twinned type: the same of input type
38  using type=T;
39  };
40 
41  /// Specify the twin component of a given TensComp
42  template <class T, // Type of which we want to declare the twin
43  class=ConstrainIsTensComp<T>> // Constrain T to be a TensComp
44  using TwinCompOf=
45  typename _TwinCompOf<T>::type;
46 
47  /// Declare a pair of TensComp twins one of the other
48 #define DECLARE_TENS_COMPS_ARE_TWIN(T1,T2)
49 
50  /*! Declare that T1 has a twin */
51  template <>
52  constexpr inline bool hasTwin<T1> =
53  true;
54 
55  MAYBE_UNUSED(hasTwin<T1>);
56 
57  /*! Declare that T2 has a twin */
58  template <>
59  constexpr inline bool hasTwin<T2> =
60  true;
61 
62  MAYBE_UNUSED(hasTwin<T2>);
63 
64  /*! Declare the twinned type of T1 */
65  template <>
66  struct _TwinCompOf<T1>
67  {
68  /*! Twinned type */
69  using type=ConstrainIsTensComp<T2>::type;
70  };
71 
72  /*! Declare the twinned type of T2 */
73  template <>
74  struct _TwinCompOf<T2>
75  {
76  /*! Twinned type */
77  using type=ConstrainIsTensComp<T1>::type;
78  }
79 
80  /// If the TensComp TC is not present in the TensKind of SMET, returns the twin
81  template <typename Tc, // Tensor Component searched
82  typename SMET, // Type of the expression where to search
83  typename=ConstrainIsTensComp<Tc>, // Constrain Tc to be a TensComp
84  typename=ConstrainIsSmET<SMET>, // Constrain SMET to be a SmET
85  typename TK=typename Unqualified<SMET>::Tk, // Tens Kind of the SmET
86  typename TK_TYPES=typename TK::types, // Types of the tensor kind
87  bool Has=tupleHasType<Tc,TK_TYPES>> // Check if the tuple has type
89 
90  /// Insert in the IntSeq the position of all true twinned types
91  ///
92  /// Internal implementation
93  template <int Pos, // Searched position
94  int...Ints, // IntSeq parameters
95  typename...T> // TensComp
96  DECLAUTO _InsertTrueTwinnedPosOfTuple(IntSeq<Ints...> in, ///< Input IntSeq
97  Tuple<T...> types) ///< Input types
98  {
99  static_assert((isTensComp<T> & ...),"Supported only for tensComp");
100 
101  // Input IntSeq
102  using In=IntSeq<Ints...>;
103  // Input Tuple
104  using Types=Tuple<T...>;
105  // Twinned Tuple
106  using TwTypes=Tuple<TwinCompOf<T>...>;
107  //
108  // Finished the types to check
109  if constexpr(sizeof...(T)<=Pos)
110  return in;
111  else
112  {
113  // Type in position Pos
115  // Twinned comp
116  using TwComp=TwinCompOf<Comp>;
117 
118  // Check if it is a real twin
120  // Check if twinned Tuple had original comp
122 
123  // Result type
125  InsertIntSeqInOrderedIntSeq<IntSeq<Pos,Pos+1>, // Position to insert
126  In, // List where to insert
127  IntSeq<0,0>, // Do not shift after inserting
128  true>, // Ignore insertion if present
129  In>;
130 
132  }
133  }
134 
135  /// Declares the twin types of a TensComp
136  ///
137  /// Forward declaration, real implementation created by the macro
138  /// which defines a twin pair
139  template <typename T>
141 
142  /////////////////////////////////////////////////////////////////
143 
144  /// Insert in the IntSeq the position of all true twinned types
145  ///
146  /// A true twinned type is a type for which the twin is different
147  /// from itself, and is present in the list
148  template <typename Is, // Integer to be extended
149  typename Tp> // Tuple to analyze
152 }
153 
154 #endif
#define MAYBE_UNUSED(A)
Suppress the "Unused Variable" warning at any scope.
Definition: Unused.hpp:23
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87
#define DECLAUTO
Short name for decltype(auto)