SUNphi  1.0
NnarySmET.hpp
Go to the documentation of this file.
1 #ifndef _NNARYSMET_HPP
2 #define _NNARYSMET_HPP
3 
4 /// \file NnarySmET.hpp
5 ///
6 /// \brief Header file defining basic properties of Nnary SmET
7 
8 #include <ints/IntSeqCat.hpp>
9 #include <smet/BaseSmET.hpp>
10 #include <smet/Reference.hpp>
11 #include <tens/TensKind.hpp>
12 #include <tuple/TupleOrder.hpp>
13 #include <utility/Position.hpp>
14 
15 namespace SUNphi
16 {
17  /// Defines the NnarySmET type traits
18  DEFINE_BASE_TYPE(NnarySmET,: public BaseSmET);
19 
20  // Defines the check for a member type "refs"
22 
23  /// Defines the check for a Nnary SmET
24 #define STATIC_ASSERT_IS_NNARY_SMET(...)
25  STATIC_ASSERT_IS_SMET(__VA_ARGS__);
26  STATIC_ASSERT_HAS_MEMBER(refs,__VA_ARGS__)
27 
28  /// Provide an identity representative function
29 #define IDENTITY_REPRESENTATIVE_FUNCTION
30  /*! Returns the argument */
31  template <typename T> /* Argument type */
32  static DECLAUTO representativeFunction(T&& t) /*!< Argument */
33  {
34  return
35  forw<T>(t);
36  }
37 
38  /// Nnary SmET
39  template <typename T> /// Inheriting type
40  struct NnarySmET :
41  public SmET<T>,
42  public BaseNnarySmET
43  {
44  IS_ASSIGNABLE_ATTRIBUTE(/*! This SmET can never be lhs */,false);
45 
47 
48  /// Evaluate the I-th reference, getting from the \c Tuple targs the element \c Pos
49  ///
50  /// Internal implementation
51  template <int I, // Reference to evaluate
52  typename Tp, // Type of the \c Tuple containing the components to call, i
53  int...Pos> // Position of the args
55  IntSeq<Pos...>, ///< List of position of components for ref
56  Tp&& targs) const ///< Components to get
57  {
58  return get<I>((~*this).refs).eval(get<Pos>(targs)...);
59  }
60 
62 
63  /// Evaluate the I-th reference, getting from the \c Tuple targs the element \c Pos
64  ///
65  /// External implementation, using \c PosOfResTcsPresInRefsTk to dispatch components
66  template <int I, // Reference to evaluate
67  typename Tp> // Type of the \c Tuple containing the components to call
68  DECLAUTO refEvalByCompsName(Tp&& targs) const ///< Components to get
69  {
70  /// Position of \c TensComp of the reference Tk present in thr result
71  using Pos=
73 
74  return _refEvalByCompsName(IntSeq<I>{},Pos{},forw<Tp>(targs));
75  }
76 
77  /// Evaluate the I-th reference, getting from the \c Tuple targs the element \c Pos
78  ///
79  /// Non const version
80  template <int I, // Reference to evaluate
81  typename Tp> // Type of the \c Tuple containing the components to call, i
83  {
85  }
86 
87  /// Evaluate the result by calling a representative function
88  ///
89  /// The result is obtained after splitting the components,
90  /// identifying them trough the name of each \c TensComp
91  template <int...I,
92  typename...Args> // Type of the arguments
94  const Args&...args) const ///< Components to get
95  {
97 
98  return (~*this).representativeFunction(this->refEvalByCompsName<I>(std::forward_as_tuple(args...))...);
99  }
100 
102  };
103 
104  /// Provides an evaluator through a representative function
105 #define EVAL_THROUGH_REPRESENTATIVE_FUNCTION_PASSING_COMPS_BY_NAME
106  /*! Evaluator, external interface */
107  /*! */
108  /*! Evaluate the function by usign a method called */
109  /*! \c representativeFunction, to be provided in the clas */
110  /*! passing to it the evaluation of each individual reference, */
111  /*! dispatching the components id by the name they have in the */
112  /*! reference */
113  template <typename...Args> /* Type of the arguments */
114  DECLAUTO eval(Args&&...args) const /* Components to get */
115  {
116  return this->evalThroughRepresentativeFunctionPassingCompsByName(IntsUpTo<NSmET>{},
117  forw<Args>(args)...);
118  }
119 
121 
122  /// Provide the references to the objects
123  ///
124  /// The reference types are contained in a \c Tuple with types
125  /// obtained from template pars
126 #define PROVIDE_NNARY_SMET_REFS_AND_CHECK_ARE_N(N)
127  /*! Type of the binding references */
128  using Refs=
129  Tuple<_Refs...>;
130 
131  /*! Reference to the N object */
132  Tuple<Reference<_Refs>...> refs;
133 
134  /*! Type of I-th \c SmET */
135  template <int I>
136  using Ref=
137  TupleElementType<I,Tuple<_Refs...>>;
138 
139  /*! Number or \c SmET to act upon */
140  static constexpr
141  int NSmET=
142  N;
143 
144  /* Check that NSmET coincides with the par */
145  static_assert(N==sizeof...(_Refs))
146 
147  /// Returns the size of a \c TensComp, with a simple approach
148  ///
149  /// Search the asked \c TensComp in each ref \c TensKind iteratively
150  /// and returns the size in the first found ref
151 #define PROVIDE_SIMPLE_NNARY_COMP_SIZE
152  /*! Returns the size in the first found ref */
153  template <typename TC, /* \c TensComp to search */
154  int I=0> /* Integer of the ref to search in */
155  int compSize() const
156  {
157  static_assert(I>=0 and I<NSmET,"Cannot search in negative or larger-than-N ref");
158 
159  /*! \c TensKind of the I-th \c SmET */
160  using RefTk=
161  typename Ref<I>::Tk;
162 
163  /*! Check if the \c TensKind contains the \c TensComp asked */
164  constexpr bool found=
165  RefTk::template contains<TC>;
166 
167  /* Returns the size if it's in the I-th Tk */
168  if constexpr(found)
169  return get<I>(refs).template compSize<TC>();
170  else
171  return compSize<TC,I+1>();
172  }
173 
174  /// Defines the \c Fund type using the call to \c representativeFunction
175 #define PROVIDE_FUND_ACCORDING_TO_REPRESENTATIVE_FUNCTION
176  /*! Fundamental type according to the \c representativeFunction */
177  /*! */
178  /*! Internal implementation, getting the type through a call to */
179  /*! the \c representativeFunction passing by value the \c Fund */
180  /*! type of each ref, using an \c IntSeq to call them */
181  template <int...Is>
182  static DECLAUTO _fundThroughRepresentativeFunction(IntSeq<Is...>)
183  {
184  return representativeFunction(typename RemRef<Ref<Is>>::Fund{}...);
185  }
186 
187  /*! Obtains the \c Fund type by calling the \c representativeFunction */
188  using Fund=
189  decltype(_fundThroughRepresentativeFunction(IntsUpTo<NSmET>{}))
190 
191  /// Get the same \c Fund type of a given ref
192 #define SAME_FUND_AS_REF(ID)
193  /*! Same \c Fund as Ref ID */
194  PROVIDE_FUND(typename RemRef<Ref<ID>>::Fund)
195 
196  /// Get the same assignability of a given ref
197 #define AS_ASSIGNABLE_AS_REF(ID)
198  IS_ASSIGNABLE_ATTRIBUTE(/*! As assignable as ref ID */,Unqualified<Ref<ID>>::isAssignable)
199 
200  /// Get the same \c TensKind of a given ref
201 #define SAME_TK_AS_REF(ID)
202  /*! Same \c TensKind as Ref ID */
203  PROVIDE_TK(typename RemRef<Ref<ID>>::Tk)
204 
205  /// Provide the position of result Tk \c TensComp in each input
206 #define PROVIDE_POS_OF_RES_TCS_IN_REFS
207  /*! Position of all the Result \c TensComp in each \c Refs Tk */
208  using PosOfResTcsInRefsTk=
209  PosOfTcsOfTkInListOfTks<Tk,typename RemRef<_Refs>::Tk...>;
210 
211  /*! Position of all the Result \c TensComp present in each \c Refs Tk */
212  using PosOfResTcsPresInRefsTk=
213  PosOfTcsOfTkPresInListOfTks<Tk,typename RemRef<_Refs>::Tk...>
214 
215  /// Determine the mergeability of the \c ResPos component of the result
216  ///
217  /// Nested internal implemention
218  template <int ResPos=0, // Current \c TensComp to be checked
219  typename...MergeDelim, // \c IntSeq containing the allowed mergeability delimiters for each Ref
220  typename...PosOfResTcsInRefTk, // Route to give the position of each \c TensComp of the Res in each Ref
221  int...PrevPosInts, // Position of previous components
222  typename ExtraDelim> // Extra delimiters to be added
225  IntSeq<PrevPosInts...>,
226  ExtraDelim)
227  {
228  static_assert(isIntSeq<ExtraDelim>,"ExtraDelim needs to be IntSeq");
229  static_assert((isIntSeq<MergeDelim> && ...),"MergeDelim need to be IntSeq");
230  static_assert((isIntSeq<PosOfResTcsInRefTk> && ...),"PosOfResTcsInRefTk need to be IntSeq");
231 
232  /// Number of remaining \c TensComp to be checked
233  constexpr int nC=
235 
236  static_assert(((nC==PosOfResTcsInRefTk::size) && ...),"All PosOfResTcsInRefTk must have the same size");
237 
238  // If we are terminating, return the final position
239  if constexpr(nC==0)
240  return IntSeq<ResPos>{};
241  else
242  {
243  /// Slice with the poisition of the current component
244  using CurPos=
246 
247  /// Nested delimiters
248  using Nested=
251  CurPos{},ExtraDelim{}));
252 
253  /// Function to check whether the current component is not consecutive in all Refs
254  constexpr auto curNotConsecutiveHelper=[](const int prevPosInt,
255  const int cur)
256  {
257  return
258  (prevPosInt!=NOT_PRESENT) and (cur!=prevPosInt+1);
259  };
260 
261  /// Check whether the current component is not consecutive in all Refs
264 
265  /// Check whether the current component was not originally mergeable
267  (MergeDelim::template has<PosOfResTcsInRefTk::first> || ...);
268 
269  /// Check where the current component is present
270  using CurPres=
272 
273  /// Check where the previous component was present
274  using PrevPres=
276 
277  /// Check it the position was extra-delimited
279  ExtraDelim::template has<ResPos>;
280 
281  /// Determine if a break in mergeability is needed
282  constexpr bool insBreak=
284  or
285  (not isSame<PrevPres,CurPres>)
286  or
288  or
290 
291  /// Insert a break or not
292  if constexpr(insBreak)
293  return IntSeqCat<IntSeq<ResPos>,Nested>{};
294  else
295  return Nested{};
296  }
297  }
298 
299  /// Determine the mergeability of a given \c TensComp
300  ///
301  /// A component is declared mergeable if its presence in all
302  /// \c TensKind is of the same nature of the previous one (e.g. present
303  /// only in one of the \c TensKind), if its position inside the
304  /// \c TensKind is consecutive with previous \c TensComp, and if the
305  /// component was mergeable in all \c TensKind
306  template <typename RefsMD, // \c Tuple of \c IntSeq containing the MergeDelims for each Ref
307  typename PosOfResTcsInRefTks, // Position of the result comps in the refs (\c Tuple of \c IntSeq)
308  typename ExtraDelims> // Additional delmiters coming from the \c SmET
311 
312  /// Add an \c ExtraDelims \c IntSeq called \c ExtraDelims
313 #define PROVIDE_EXTRA_MERGE_DELIMS(...)
314  /*! Additional delimiters */
315  using ExtraDelims=
316  __VA_ARGS__
317 
318  /// Add an empty \c ExtraDelims
319 #define NO_EXTRA_MERGE_DELIMS
320  /*! No Additional MergeDelims is included */
322 
323  /// Provide \c MergeableComps delimiter according to references and extra
324 #define PROVIDE_MERGEABLE_COMPS_ACCORDING_TO_REFS_AND_EXTRA
325  PROVIDE_MERGEABLE_COMPS(/*! Using \c MergingDelimsForRefs and \c ExtraDelims to determine the mergability */,
326  NnarySmETCompsMergeability<
327  Tuple<typename RemRef<_Refs>::MergeableComps...>,
328  PosOfResTcsInRefsTk,
329  ExtraDelims>)
330 
331  /////////////////////////////////////////////////////////////////
332 
333  /// Returns the merged comps view of the \c I-th \c Ref
334 #define MERGED_COMPS_VIEW_OF_REF(I)
335  get<I>(refs).template getMergedCompsView<TupleElementType<I,MDs>>()
336 
337  /// Provides a \c getMergedCompsView method, taking Is as template parameter
338 #define PROVIDE_NNARY_GET_MERGED_COMPS_VIEW(DESCRIPTION,...)
339  DESCRIPTION
340  template <typename Is> /* IntSeq delimiting the comps groups */
341  DECLAUTO getMergedCompsView()
342  const
343  {
344  /* Check that we can merge as asked */
345  assertMergeableWith<Is>();
346 
347  using MDs=
348  Tuple<InsertInOrderedIntSeq /* Insert the begin */
349  <0, /* Insert 0 as begin */
350  IntSeqGetElsAfterAppending
351  <RemRef<_Refs>::Tk::nTypes,
352  false, /* Omit NOT_PRESENT */
353  Is,
354  PosOfTypesNotAsserting<typename Tk::types,
355  typename RemRef<_Refs>::Tk::types>>,
356  0, /* Shift after inserting */
357  true>...>; /* Ignore 0 if present */
358 
359  __VA_ARGS__;
360  }
361 
362  PROVIDE_ALSO_NON_CONST_METHOD(getMergedCompsView)
363 
364  /// Uses the \c representativeFunction to provide a merged view
365 #define PROVIDE_NNARY_GET_MERGED_COMPS_VIEW_ACCORDING_TO_REPRESENTATIVE_FUNCTION
366  /*! Calls the \c representativeFunction with the merged view of each ref */
367  template <int...Is, /* Ints used to call the representativeFunction */
368  typename MDs> /* MergeDelims to be used */
369  DECLAUTO mergedCompsViewAccordingToRepresentativeFunction(IntSeq<Is...>,
370  MDs) const
371  {
372  return representativeFunction(MERGED_COMPS_VIEW_OF_REF(Is)...);
373  }
374 
375  PROVIDE_ALSO_NON_CONST_METHOD(mergedCompsViewAccordingToRepresentativeFunction);
376 
377  PROVIDE_NNARY_GET_MERGED_COMPS_VIEW(/*! Uses the \c representativeFunction to provide a merged view */,
378  return mergedCompsViewAccordingToRepresentativeFunction(IntsUpTo<NSmET>{},MDs{}))
379 
380  /////////////////////////////////////////////////////////////////
381 
382  /// Defines a simple creator taking n references
383 #define PROVIDE_NNARY_SMET_SIMPLE_CREATOR(NNARY_SMET /*!< Name of the NnarySmET */)
384  /*! Constructor taking universal reference */
385  template <typename...SMETS,
386  typename=EnableIf<((isSame<Unqualified<SMETS>,Unqualified<_Refs>>) && ...)>>
387  explicit NNARY_SMET(SMETS&&...smets) : refs(forw<SMETS>(smets)...)
388  {
389  }
390 
391  /////////////////////////////////////////////////////////////////
392 
393  /// Defines the check for a NnarySmET
394 #define STATIC_ASSERT_IS_NNARY_SMET(...)
395  STATIC_ASSERT_IS_SMET(__VA_ARGS__);
396  STATIC_ASSERT_HAS_MEMBER(refs,__VA_ARGS__)
397 
398  /////////////////////////////////////////////////////////////////
399 
400  /// Create a simple builder with a name and a NNARY_SMET returned type
401  ///
402  /// \c NnarySmET cannot use SFINAE to worsen default constructors
403  /// (unless packing args in \c Tuple) so the simple builder cannot
404  /// be overloaded. If required, use a custom builder and use if
405  /// constexpr construct inside it to route the manipulations.
406 #define SIMPLE_NNARY_SMET_BUILDER(BUILDER, /*!< Name of builder function */
407  NNARY_SMET) /*!< Name of the NnarySmET to build */
408  /*! Simple NNARY_SMET builder called BUILDER */
409  /*! */
410  /*! Plain NNARY_SMET getting n plain SmET */
411  template <typename...Ts> /* Types of the SmET to get */
412  NNARY_SMET<Ts...> BUILDER(Ts&&...smets) /*!< SmETs to act upon */
413  {
414  return NNARY_SMET<Ts...>(forw<Ts>(smets)...);
415  }
417 
418  /// Set aliasing according to the isAliasing of references
419  /// \todo enforce cehck only with TensClass
420 #define FORWARD_IS_ALIASING_TO_REFS
421  /*! Forward aliasing check to the references */
422  template <typename Tref>
423  bool isAliasing(const Tref& alias) const
424  {
425  CRASH<<"Fixme";
426 
427  return
428  true;
429  }
430 
431  /// Provides \c Fund, \c eval and \c mergedComps according to \c representativeFunction
432 #define REPRESENTATIVE_FUNCTION_WINS_ALL
434 
436 
438 
440 
442 
443 
444  /// Implements a duplicated-call canceller
445  ///
446  /// Example
447  /// \code
448  /// Tens<TensKind<Compl>,double> cicc;
449  /// conj(conj(cicc)); // returns cicc
450  /// \endcode
451 #define CANCEL_DUPLICATED_NNARY_SMET_CALL(CALLER, /*!< Name of builder */
452  NNARY_SMET) /*!< Type to un-nest */
453  /*! Simplify CALLER(NNARY_SMET) expression */
454  /*! */
455  /*! Returns the nested reference */
456  template <typename T, /* Type of the expression */
457  typename RrT=RemRef<T>, /* T without ref attributes */
458  typename Ref=typename RrT::template Ref<0>, /* Type of the reference */
459  typename RrRef=RemRef<Ref>, /* Ref without ref attributes */
460  bool SmETIsLvalue=isLvalue<RrT>, /* Detect if SmET is an lvalue */
461  bool RefIsLvalue=isLvalue<RrRef>, /* Detect if Ref is an lvalue */
462  bool RefIsStoring=isStoring<RrRef>, /* Detect if Ref is storing */
463  bool RetByRef=RefIsStoring or /* Returns by val if Ref is storing, or */
464  RefIsLvalue or SmETIsLvalue, /* lvalue is involved */
465  typename Ret=Conditional<RetByRef,RrRef&,RrRef>, /* Returned type */
466  SFINAE_ON_TEMPLATE_ARG(is ## NNARY_SMET<RrT>)> /* Enable only for the NNARY_SMET required */
467  Ret CALLER(T&& smet) /*!< Quantity to un-nest */
468  {
469  if constexpr(0)
470  {
471  constexpr bool SmETIsConst=isConst<T>;
472  constexpr bool RefIsConst=isConst<Ref>;
473 
474  using namespace std;
475  cout<<"Removing duplicated call " # CALLER<<" "<<__PRETTY_FUNCTION__<<endl;
476  constexpr bool SmETIs=std::is_reference<T>::value;
477  constexpr bool RefIs=std::is_reference<Ref>::value;
478  cout<<" SmETIsLvalue: "<<SmETIsLvalue<<endl;
479  cout<<" SmETIs: "<<SmETIs<<endl;
480  cout<<" SmETIsConst: "<<SmETIsConst<<endl;
481  cout<<" RefIsLvalue: "<<RefIsLvalue<<endl;
482  cout<<" RefIs: "<<RefIs<<endl;
483  cout<<" RefIsConst: "<<RefIsConst<<endl;
484  }
485 
486  return static_cast<Ret>(get<0>(smet.refs));
487  }
489 
490  /// Defines a simple way to swap nested \c NnarySmET
491  ///
492  /// \todo we need to implement the same check done for
493  /// \c CANCEL_DUPLICATED_NNARY_SMET_CALL
494 #define NNARY_SMET_GOES_INSIDE(EXT_FUN, /*!< External builder */
495  NNARY_SMET, /*!< Name of the SmET */
496  INT_FUN) /*!< Internal builder */
497  /*! Simplify EXT_FUN(NNARY_SMET u) expression */
498  /*! */
499  /*! Returns INT_FUN(EXT_FUN(u.ref)) */
500  template <typename D, /* Type of the nested NNARY_SMET */
501  SFINAE_ON_TEMPLATE_ARG(is ## NNARY_SMET<D>)> /* Enable only for the NNARY_SMET required */
502  DECLAUTO EXT_FUN(D&& smet) /*!< NnarySmET to nest */
503  {
504  return INT_FUN(EXT_FUN(get<0>(smet.refs)));
505  }
507 
508  /// Implements a duplicated-call absorber
509  ///
510  /// Example
511  /// \code
512  /// Tens<TensKind<Compl>,double> cicc;
513  /// wrap(wrap(cicc)); // returns wrap(cicc)
514  /// \endcode
515 #define ABSORB_DUPLICATED_NNARY_SMET_CALL(CALLER, /*!< Name of builder */
516  NNARY_SMET) /*!< Type to absorb */
517  /*! Simplify CALLER(NNARY_SMET) expression */
518  /*! */
519  /*! Returns the reference */
520  template <typename D, /* Type of the nested NNARY_SMET */
521  SFINAE_ON_TEMPLATE_ARG(is ## NNARY_SMET<D>)> /* Enable only for the NNARY_SMET required */
522  DECLAUTO CALLER(D&& smet) /*!< NnarySmET to absorb */
523  {
524  return forw<D>(smet);
525  }
527 
528 }
529 
530 #endif
#define MERGED_COMPS_VIEW_OF_REF(I)
Returns the merged comps view of the I-th Ref.
Definition: NnarySmET.hpp:334
#define PROVIDE_NNARY_GET_MERGED_COMPS_VIEW_ACCORDING_TO_REPRESENTATIVE_FUNCTION
Uses the representativeFunction to provide a merged view.
Definition: NnarySmET.hpp:365
#define DEFINE_HAS_MEMBER(TAG)
Definition: TypeTraits.hpp:581
#define STATIC_ASSERT_IS_SMET(...)
Definition: BaseSmET.hpp:257
#define EVAL_THROUGH_REPRESENTATIVE_FUNCTION_PASSING_COMPS_BY_NAME
Provides an evaluator through a representative function.
Definition: NnarySmET.hpp:105
#define PROVIDE_POS_OF_RES_TCS_IN_REFS
Provide the position of result Tk TensComp in each input.
Definition: NnarySmET.hpp:206
#define STATIC_ASSERT_ARE_N_TYPES(N, UNEXP_PARPACK)
Static assert if not passing exactly N types.
Definition: TypeTraits.hpp:422
#define PROVIDE_TK(...)
Provides the Tk member.
Definition: BaseSmET.hpp:94
#define PROVIDE_MERGEABLE_COMPS_ACCORDING_TO_REFS_AND_EXTRA
Provide MergeableComps delimiter according to references and extra.
Definition: NnarySmET.hpp:324
#define PROVIDE_FUND(...)
Provides the Fund member.
Definition: BaseSmET.hpp:108
#define CRASH
Initialize the crasher.
Definition: Crash.hpp:13
#define PROVIDE_CRTP_CAST_OPERATOR(CLASS)
Definition: CRTP.hpp:16
#define CALL_CLASS_CONST_METHOD_REMOVING_CONST(...)
Call a const method removing any const qualifier.
Definition: TypeTraits.hpp:352
#define PROVIDE_MERGEABLE_COMPS(LONG_DESCRIPTION,...)
Definition: BaseSmET.hpp:179
#define PROVIDE_NNARY_GET_MERGED_COMPS_VIEW(DESCRIPTION,...)
Provides a getMergedCompsView method, taking Is as template parameter.
Definition: NnarySmET.hpp:338
#define IS_ASSIGNABLE_ATTRIBUTE(LONG_DESCRIPTION,...)
Provides a isAssignable attribute.
Definition: BaseSmET.hpp:155
#define SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
#define PROVIDE_EXTRA_MERGE_DELIMS(...)
Add an ExtraDelims IntSeq called ExtraDelims.
Definition: NnarySmET.hpp:313
#define SFINAE_ON_TEMPLATE_ARG(...)
Definition: SFINAE.hpp:24
#define PROVIDE_FUND_ACCORDING_TO_REPRESENTATIVE_FUNCTION
Defines the Fund type using the call to representativeFunction.
Definition: NnarySmET.hpp:175
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87
#define PROVIDE_ALSO_NON_CONST_METHOD(NAME)
Definition: TypeTraits.hpp:376
Smart Expression Templates.
Definition: BaseSmET.hpp:271
#define DECLAUTO
Short name for decltype(auto)
#define STATIC_ASSERT_HAS_MEMBER(TAG,...)
Definition: TypeTraits.hpp:560
decltype(auto) evalThroughRepresentativeFunctionPassingCompsByName(Ts &&...ts)
Definition: NnarySmET.hpp:101
decltype(auto) constexpr _nnarySmETCompsMergeability(Tuple< MergeDelim... >, Tuple< PosOfResTcsInRefTk... >, IntSeq< PrevPosInts... >, ExtraDelim)
Definition: NnarySmET.hpp:223
#define DEFINE_BASE_TYPE(TYPE,...)
Definition: TypeTraits.hpp:526