SUNphi  1.0
IntSeqRemove.hpp
Go to the documentation of this file.
1 #ifndef _INTSEQREMOVE_HPP
2 #define _INTSEQREMOVE_HPP
3 
4 /// \file IntSeqRemove.hpp
5 
6 #include <ints/IntListOrder.hpp>
7 #include <ints/IntSeq.hpp>
8 #include <metaprogramming/UniversalReferences.hpp>
9 
10 namespace SUNphi
11 {
12  /// Remove the integer Ins in order of HeadAft,TailAft...
13  ///
14  /// Technically, the two IntSeq do not have to be ordered, the
15  /// removal is done when HeadAft is largeer than Rem. The elements
16  /// after are incremented by IncrAft. The removal is always accepted
17  /// if IgnoreIfPresent is true.
18  template <int Rem, // Element to remove
19  int IncrAft, // Increment after the found position
20  bool IgnoreIfNotPresent, // Ignore removal if not present
21  int...Bef, // Elements parsed so far
22  int HeadAft, // Next element to parse
23  int...TailAft> //Other elements to parse
25  {
26  // Need to be removed now
27  if constexpr(Rem<=HeadAft)
28  // Present from the beginning
29  if constexpr(Rem==HeadAft)
30  return IntSeq<Bef...,(TailAft+IncrAft)...>{};
31  else
32  {
33  // If it was not present, check that we are fine with ignoring
34  static_assert(Rem!=HeadAft or IgnoreIfNotPresent,"Cannot ignore the absence");
35  return IntSeq<Bef...,HeadAft+IncrAft,(TailAft+IncrAft)...>{};
36  }
37  else
38  // Move head to the left and nest
39  if constexpr(sizeof...(TailAft)>0)
40  return _removeFromOrderedIntSeq<Rem,IncrAft,IgnoreIfNotPresent>(IntSeq<Bef...,HeadAft>{},IntSeq<TailAft...>{});
41  else
42  // Return the full
43  return IntSeq<Bef...,HeadAft>{};
44  }
45 
46  /// Remove the integer Ins in a previously empty IntSeq
47  template <int Rem,
48  int IncrAft,
49  bool IgnoreIfPresent>
50  DECLAUTO _removeFromOrderedIntSeq(const IntSeq<>&,const IntSeq<>&)
51  {
52  return IntSeq<>{};
53  }
54 
55  /// Remove the integer Rem in an ordered IntSeq
56  ///
57  /// The elements after are incremented by IncrAft. The removal is
58  /// valid if IgnoreIfNotPresent is true. Examples:
59  ///
60  /// \code
61  /// using A=IntSeq<0,1,3>;
62  /// using B=RemoveFromOrderedIntSeq<w,A,10,true>; // IntSeq<0,1,13>
63  /// INVALID using C=InsertInOrderedIntSeq<3,A,10,false>; // IntSeq<0,1,3,13>
64  /// \endcode
65  template <int Ins,
66  typename IS,
67  int IncrAft=0,
68  bool IgnoreIfNotPresent=true>
69  using RemoveFromOrderedIntSeq=
70  decltype(_removeFromOrderedIntSeq<Ins,IncrAft,IgnoreIfNotPresent>(IntSeq<>{},typename ConstrainIsOrderedIntSeq<Unqualified<IS>>::type{}));
71 
72  /// Remove the integer Rem from an ordered unique IntSeq
73  ///
74  /// Care is taken to ensure that Ins is not already in IS The
75  /// elements after are incremented by IncrAft. See
76  /// RemovefromOrderedIntSeq for examples
77  template <int Ins,
78  typename IS,
79  int IncrAft=0,
80  bool IgnoreIfPresent=false>
81  using RemoveFromOrderedUniqueIntSeq=
82  typename ConstrainIsOrderedUniqueIntSeq<
83  decltype(_removeFromOrderedIntSeq<Ins,IncrAft,IgnoreIfPresent>
84  (IntSeq<>{},typename ConstrainIsOrderedUniqueIntSeq<IS>::type{}))>::type;
85 }
86 
87 #endif
decltype(auto) _removeFromOrderedIntSeq(const IntSeq< Bef... > &, const IntSeq< HeadAft, TailAft... > &)
#define DECLAUTO
Short name for decltype(auto)