SUNphi  1.0
IntSeqInsert.hpp
Go to the documentation of this file.
1 #ifndef _INTSEQINSERT_HPP
2 #define _INTSEQINSERT_HPP
3 
4 /// \file IntSeqInsert.hpp
5 
6 #include <ints/IntListOrder.hpp>
7 #include <ints/IntSeq.hpp>
8 #include <ints/Ranges.hpp>
9 #include <metaprogramming/UniversalReferences.hpp>
10 
11 namespace SUNphi
12 {
13  /// Insert the integer Ins in order of HeadAft,TailAft...
14  ///
15  /// Technically, the two IntSeq do not have to be ordered, the
16  /// insertion is done when HeadAft is larger than Ins. The elements
17  /// after are incremented by IncrAft. The insertion is ignored if
18  /// IgnoreIfPresent is true.
19  template <int Ins, // Element to insert
20  int IncrAft, // Increment after the found position
21  bool IgnoreIfPresent, // Ignore insertion if already present
22  int...Bef, // Elements parsed so far
23  int HeadAft, // Next element to parse
24  int...TailAft> //Other elements to parse
26  {
27  // Need to be inserted now
28  if constexpr(Ins<=HeadAft)
29  // Returns original IntSeq
30  if constexpr(Ins==HeadAft and IgnoreIfPresent)
31  return IntSeq<Bef...,HeadAft,TailAft...>{};
32  else
33  // Insert and shift
34  return IntSeq<Bef...,Ins,HeadAft+IncrAft,(TailAft+IncrAft)...>{};
35  else
36  // Move head to the left and nest
37  if constexpr(sizeof...(TailAft)>0)
38  return _insertInOrderedIntSeq<Ins,IncrAft,IgnoreIfPresent>(IntSeq<Bef...,HeadAft>{},IntSeq<TailAft...>{});
39  else
40  // Put at the end
41  return IntSeq<Bef...,HeadAft,Ins>{};
42  }
43 
44  /// Insert the integer Ins in a previously empty IntSeq
45  template <int Ins,
46  int IncrAft,
47  bool IgnoreIfPresent>
48  DECLAUTO _insertInOrderedIntSeq(const IntSeq<>&,const IntSeq<>&)
49  {
50  return IntSeq<Ins>{};
51  }
52 
53  /// Insert the integer Ins in an ordered IntSeq
54  ///
55  /// The elements after are incremented by IncrAft. The insertion is
56  /// ignored if IgnoreIfPresent is true. Examples:
57  ///
58  /// \code
59  /// using A=IntSeq<0,1,3>;
60  /// using B=InsertInOrderedIntSeq<3,A,10,true>; // IntSeq<0,1,3>
61  /// using C=InsertInOrderedIntSeq<3,A,10,false>; // IntSeq<0,1,3,13>
62  /// \endcode
63  template <int Ins,
64  typename IS,
65  int IncrAft=0,
66  bool IgnoreIfPresent=false>
67  using InsertInOrderedIntSeq=
68  decltype(_insertInOrderedIntSeq<Ins,IncrAft,IgnoreIfPresent>(intSeq<>,typename ConstrainIsOrderedIntSeq<IS>::type{}));
69 
70  /////////////////////////////////////////////////////////////////
71 
72  /// Insert the elements of the IntSeq Is in an ordered IntSeq
73  ///
74  ///Internal implementation
75  template <bool IgnoreIfPresent,
76  int HeadToIns,
77  int...TailToIns,
78  int HeadIncrAft,
79  int...TailIncrAft,
80  typename Is>
83  const Is&)
84  {
85  // Insert HeadToIns
86  InsertInOrderedIntSeq<HeadToIns,Is,HeadIncrAft,IgnoreIfPresent> tmp;
87 
88  // Returns HeadToIns insertion alone if no more present
89  if constexpr(sizeof...(TailToIns)==0)
90  return tmp;
91  // Nest otherwise
92  else
93  return _InsertIntSeqInOrderedIntSeq<IgnoreIfPresent>(intSeq<TailToIns...>,intSeq<TailIncrAft...>,tmp);
94  }
95 
96  /// Insert the elements of the IntSeq Is in an ordered IntSeq
97  ///
98  /// Internal implementation, empty case
99  template <bool IgnoreIfPresent,
100  typename Is>
101  DECLAUTO _InsertIntSeqInOrderedIntSeq(const IntSeq<>& noIns,const IntSeq<>& noIncrAft,const Is&)
102  {
103  return Is{};
104  }
105 
106  /// Insert the elements of the IntSeq Is in an ordered IntSeq
107  template <typename ToIns, // IntSeq to be inserted
108  typename Is, // IntSeq where to insert
109  typename IncrAft=IntSeqOfSameNumb<ToIns::size,0>, // IntSeq of increments
110  bool IgnoreIfPresent=false, // If set true, ignore each already present entry
111  typename=EnableIf<isIntSeq<ToIns> and // Checks that ToIns is an IntSeq
112  isIntSeq<IncrAft> and // Checks that IncrAft is an IntSeq
113  ToIns::size==IncrAft::size>> // Checks that ToIns and IncrAft have the same number of entries
114  using InsertIntSeqInOrderedIntSeq=
115  decltype(_InsertIntSeqInOrderedIntSeq<IgnoreIfPresent>(ToIns{},IncrAft{},Is{}));
116 }
117 
118 #endif
decltype(auto) _insertInOrderedIntSeq(const IntSeq< Bef... > &, const IntSeq< HeadAft, TailAft... > &)
decltype(auto) _InsertIntSeqInOrderedIntSeq(const IntSeq< HeadToIns, TailToIns... > &toIns, const IntSeq< HeadIncrAft, TailIncrAft... > &incrAft, const Is &)
#define DECLAUTO
Short name for decltype(auto)