SUNphi  1.0
BinarySmET.hpp
Go to the documentation of this file.
1 #ifndef _BINARYSMET_HPP
2 #define _BINARYSMET_HPP
3 
4 /// \file BinarySmET.hpp
5 ///
6 /// \brief Header file defining basic properties of Binary SmET
7 
8 #include <ints/IntSeqCat.hpp>
9 #include <smet/BaseSmET.hpp>
10 #include <utility/Position.hpp>
11 
12 namespace SUNphi
13 {
14  /// Defines the BinarySmET type traits
15  DEFINE_BASE_TYPE(BinarySmET,: public BaseSmET);
16 
17  // Defines the check for a member type "ref1"
19 
20  // Defines the check for a member type "ref2"
22 
23  /// Defines the check for a Binary SmET
24 #define STATIC_ASSERT_IS_BINARY_SMET(...)
25  STATIC_ASSERT_IS_SMET(__VA_ARGS__);
26  STATIC_ASSERT_HAS_MEMBER(ref1,__VA_ARGS__);
27  STATIC_ASSERT_HAS_MEMBER(ref2,__VA_ARGS__)
28 
29  /// Binary SmET
30  template <typename T>
31  struct BinarySmET :
32  public SmET<T>,
33  public BaseBinarySmET
34  {
35  IS_ASSIGNABLE_ATTRIBUTE(/*! This SmET can never be lhs */,false);
36 
38  };
39 
40  /// Provide the reference to the objects
41 #define PROVIDE_BINARY_SMET_REFS
44 
45  /////////////////////////////////////////////////////////////////
46 
47  /// Defines a simple creator taking a reference
48 #define PROVIDE_BINARY_SMET_SIMPLE_CREATOR(BINARY_SMET /*!< Name of the BinarySmET */)
49  /*! Constructor taking universal reference */
50  template <typename SMET1,
51  typename SMET2,
52  typename=EnableIf<isSame<Unqualified<SMET1>,Unqualified<Ref1>>>,
53  typename=EnableIf<isSame<Unqualified<SMET2>,Unqualified<Ref2>>>>
54  explicit BINARY_SMET(SMET1&& smet1,SMET2&& smet2) : ref1(forw<SMET1>(smet1)),ref2(forw<SMET2>(smet2))
55  {
56  }
57 
58  /////////////////////////////////////////////////////////////////
59 
60  /// Create a simple builder with a name and a BINARY_SMET returned type
61 #define SIMPLE_BINARY_SMET_BUILDER(BUILDER, /*!< Name of builder function */
62  BINARY_SMET) /*!< Name of the BinarySmET to build */
63  /*! Simple BINARY_SMET builder called BUILDER */
64  /*! */
65  /*! Plain BINARY_SMET getting a pair of plain SmET */
66  template <typename T1, /* Type of the first SmET to get */
67  typename T2, /* Type of the second SmET to get */
69  BINARY_SMET<T1,T2> BUILDER(T1&& smet1, /*!< First SmET to act upon */
70  T2&& smet2, /*!< Second SmET to act upon */
72  {
74 
75  return BINARY_SMET<T1,T2>(forw<T1>(smet1),forw<T2>(smet2));
76  }
78 
79  /// Set aliasing according to the isAliasing of references 1 and 2
80  /// \todo enforce cehck only with TensClass
81 #define FORWARD_IS_ALIASING_TO_PAIR_OF_REFS
82  /*! Forward aliasing check to the references */
83  template <typename Tref>
84  bool isAliasing(const Tref& alias) const
85  {
86  return
87  ref1.isAliasing(alias) or
88  ref2.isAliasing(alias);
89  }
90 
91  /// Determine mergeability of pair of \c TensKind
93  {
94  /// Type returned when is absent in both
95  using AbsentInBoth=
96  IntSeq<false,false>;
97 
98  /// Determine the mergeability of a given \c TensComp
99  ///
100  /// Terminator of the nested implementation, returning an \c
101  /// IntSeq holding just the current searched position, as a final
102  /// delimiter
103  template <typename PrevPres=AbsentInBoth, // Previous position presence
104  int ResPos=0, // Position in the result probed
105  int PrevPos1=0, // Previous position in the first \c TensKind
106  int PrevPos2=0, // Previous position in the second \c TensKind
107  int...MDel1, // Mergeability delimiters of first \c SmET
108  int...MDel2> // Mergeability delimiters of second \c SmET
109  DECLAUTO _compsMergeability(IntSeq<MDel1...> MD1, ///< Holds the mergeability delimiters of first \c SmET
110  IntSeq<MDel2...> MD2, ///< Holds the mergeability delimiters of second \c SmET
111  IntSeq<> P1, ///< Holds the position of first \c SmET where the \c Res \c TensComp are found
112  IntSeq<> P2) ///< Holds the position of second \c SmET where the \c Res \c TensComp are found
113  {
114  return IntSeq<ResPos>{};
115  }
116 
117  /// Determine the mergeability of a given \c TensComp, provided two \c TensKind
118  ///
119  /// Nested internal implementation, catting the current component
120  /// with the tail mergeability.
121  template <typename PrevPres=AbsentInBoth, // Previous position presence
122  int ResPos=0, // Position probed
123  int PrevPos1=0, // Previous position in the first \c TensKind
124  int PrevPos2=0, // Previous position in the second \c TensKind
125  int...MDel1, // Mergeability delimiters of first \c SmET
126  int...MDel2, // Mergeability delimiters of second \c SmET
127  int Head1, // Current component position in the first \c SmET
128  int...Tail1, // Other components position in the first \c SmET
129  int Head2, // Current component position in the second \c SmET
130  int...Tail2> // Other components position in the second \c SmET
131  DECLAUTO _compsMergeability(IntSeq<MDel1...> MD1, ///< Holds the mergeability delimiters of first \c SmET
132  IntSeq<MDel2...> MD2, ///< Holds the mergeability delimiters of second \c SmET
133  IntSeq<Head1,Tail1...> P1, ///< Holds the position of first \c SmET where the \c TensComp is found
134  IntSeq<Head2,Tail2...> P2) ///< Holds the position of second \c SmET where the \c TensComp is found
135  {
136  /// Presence of current position
137  using CurPres=
139  static_assert(not isSame<CurPres,AbsentInBoth>,"Cannot be AbsentInBoth");
140 
141  /// Check consecutivity in first \c TensKind
144  and
145  (Head1!=PrevPos1+1);
146 
147  /// Check consecutivity in second \c TensKind
150  and
151  (Head2!=PrevPos2+1);
152 
153  /// Result of mergeability of nested components
154  using Nested=
156 
157  /// Check if the component was mergeable in the first \c TensKind
159  ((MDel1==Head1) || ...);
160 
161  /// Check if the component was mergeable in the second \c TensKind
163  ((MDel2==Head2) || ...);
164 
165  /// Determine if a break in mergeability is needed
166  constexpr bool insBreak=
168  or
170  or
171  (not isSame<PrevPres,CurPres>)
172  or
174  or
176 
177  /// Insert a break or not
178  if constexpr(insBreak)
179  return IntSeqCat<IntSeq<ResPos>,Nested>{};
180  else
181  return Nested{};
182  }
183 
184  /// Determine the mergeability of a given \c TensComp
185  ///
186  /// A component is declared mergeable if its presence in the two
187  /// \c TensKind is of the same nature of the previous one
188  /// (e.g. present only in one of the two \c TensKind, if its
189  /// position inside the two \c TensKind is consecutive with
190  /// previous \c TensComp, and if the component was mergeable in
191  /// both \c TensKind
192  template <typename MD1,
193  typename MD2,
194  typename I1,
195  typename I2>
196  using CompsMergeability=
198 
199  /// Provide component-mergeabilty according to the two refs, and the visible \c Tk
200  ///
201  /// \todo check that this is general enough... probably not
202 #define PROVIDE_MERGEABLE_COMPS_ACCORDING_TO_TWO_REFS
203  PROVIDE_MERGEABLE_COMPS(/*! Defer the mergeability to the internal implementation */,
204  PairOfTensKindMergeability::template CompsMergeability<
205  typename RemRef<Ref1>::MergeableComps,
206  typename RemRef<Ref2>::MergeableComps,
207  PosOfRef1TcsInResTk,
208  PosOfRef2TcsInResTk>)
209  }
210 }
211 
212 #endif
#define DEFINE_HAS_MEMBER(TAG)
Definition: TypeTraits.hpp:581
Binary SmET.
Definition: BinarySmET.hpp:31
#define STATIC_ASSERT_IS_SMET(...)
Definition: BaseSmET.hpp:257
decltype(auto) _compsMergeability(IntSeq< MDel1... > MD1, IntSeq< MDel2... > MD2, IntSeq< Head1, Tail1... > P1, IntSeq< Head2, Tail2... > P2)
Definition: BinarySmET.hpp:131
#define PROVIDE_CRTP_CAST_OPERATOR(CLASS)
Definition: CRTP.hpp:16
#define SFINAE_WORSEN_DEFAULT_VERSION_TEMPLATE_PARS
Definition: SFINAE.hpp:58
#define PROVIDE_SMET_REF(NUM)
Provide the reference to the object.
Definition: Reference.hpp:29
#define PROVIDE_MERGEABLE_COMPS(LONG_DESCRIPTION,...)
Definition: BaseSmET.hpp:179
#define IS_ASSIGNABLE_ATTRIBUTE(LONG_DESCRIPTION,...)
Provides a isAssignable attribute.
Definition: BaseSmET.hpp:155
#define SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
static constexpr int element()
Get the I element of the sequence.
Definition: IntSeq.hpp:95
#define SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK
Check that no extra arg is passed.
Definition: SFINAE.hpp:66
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87
Smart Expression Templates.
Definition: BaseSmET.hpp:271
#define SFINAE_WORSEN_DEFAULT_VERSION_ARGS
Provide empty list of args, used to unprioritize default version.
Definition: SFINAE.hpp:62
#define DECLAUTO
Short name for decltype(auto)
#define STATIC_ASSERT_HAS_MEMBER(TAG,...)
Definition: TypeTraits.hpp:560
#define DEFINE_BASE_TYPE(TYPE,...)
Definition: TypeTraits.hpp:526