SUNphi  1.0
IntListOrder.hpp
Go to the documentation of this file.
1 #ifndef _INTLISTORDER_HPP
2 #define _INTLISTORDER_HPP
3 
4 /// \file IntListOrder.hpp
5 ///
6 /// \brief Implements order check and operations on integer list
7 
8 namespace SUNphi
9 {
10  /// Compare the order of at least two integers
11  ///
12  /// Return true if First<Second or First==Second (only if
13  /// AlsoEqual==true). Call iteratively itself if more than two
14  /// arguents are passed.
15  template <bool AlsoEqual, // Flag to return true if First==Second
16  int First, // First element to compare
17  int Second, // Second element to compare
18  int...Tail> // Other elements to compare
19  constexpr bool _areOrderedMin2Ints();
20 
21  /// Compare a list of integer
22  ///
23  /// If less than two elements are pased, returns true. Otherwise
24  /// call the routine which operates on at least two integers
25  template <bool AlsoEqual, // Flag to return true if First==Second
26  int...Ints> // List of integers to compare
27  constexpr bool _areOrdered()
28  {
29  if constexpr(sizeof...(Ints)<2)
30  return true;
31  else
32  return _areOrderedMin2Ints<AlsoEqual,Ints...>();
33  }
34 
35  // Actual implementation (see above for comments)
36  template <bool AlsoEqual,
37  int First,
38  int Second,
39  int...Tail>
40  constexpr bool _areOrderedMin2Ints()
41  {
42  constexpr bool compa=AlsoEqual?(First<=Second):(First<Second);
43 
44  return compa and _areOrdered<AlsoEqual,Second,Tail...>();
45  }
46 
47  /// Returns true if all elements are ascending-ordered and different
48  template <int...Ints>
49  [[ maybe_unused ]]
50  constexpr bool areOrdered=
51  _areOrdered<true,Ints...>();
52 
53  /// Returns true if all elements are weak ascending-ordered
54  template <int...Ints>
55  [[ maybe_unused ]]
56  constexpr bool areOrderedAndDifferent=
57  _areOrdered<false,Ints...>();
58 
59  /////////////////////////////////////////////////////////////////////////
60 
61  /// Constant used to parse first-occurrency case
62 #define FIRST_OF 0
63 
64  /// Constant used to parse last-occurrency case
65 #define LAST_OF 1
66 
67  /// Defines a searcher named NAME making the comparison COMPA with an external I
68 #define DEFINE_SEARCH(DESCRIPTION,FIRST_OR_LAST,NAME,COMPA)
69  DESCRIPTION
70  /*! */
71  /*! Internal implementation */
72  template <int I, /* Element to search */
73  int Pos, /* Position currently reached */
74  int NParsed, /* Number of elements already parsed */
75  int Head, /* First component to be searched */
76  int...Tail> /* Other components */
77  constexpr int _ ## NAME()
78  {
79  constexpr bool matching=(Head COMPA I);
80  constexpr bool exitAtFirst=(FIRST_OR_LAST==FIRST_OF);
81  constexpr bool emptyTail=(sizeof...(Tail)==0);
82  constexpr int newPos=(matching?NParsed:Pos);
83 
84  if constexpr((not emptyTail) and not (matching and exitAtFirst))
85  return _ ## NAME<I,newPos,NParsed+1,Tail...>();
86  else
87  if constexpr(matching and (exitAtFirst or emptyTail))
88  return newPos;
89  else
90  return newPos;
91  }
92 
93  DESCRIPTION
94  /*! */
95  /*! General case */
96  template <int I, /* Element to search */
97  int...Ints> /* Components */
98  [[ maybe_unused ]]
99  constexpr int NAME=
100  _ ## NAME<I,sizeof...(Ints),0,Ints...>();
101 
102  DESCRIPTION
103  /*! */
104  /*! Empty sequence case */
105  template <int I> /* Element to search */
106  constexpr int NAME<I> =
107  0
108 
109  DEFINE_SEARCH(/*! Returns the position of the first element different from I */,FIRST_OF,firstNon,!=);
110  DEFINE_SEARCH(/*! Returns the position of the last element different from I */,LAST_OF,lastNon,!=);
111 
112  DEFINE_SEARCH(/*! Returns the position of the first element equal to I */,FIRST_OF,firstEq,==);
113  DEFINE_SEARCH(/*! Returns the position of the last element equal to I */,LAST_OF,lastEq,==);
114 
115  DEFINE_SEARCH(/*! Returns the position of the first element smaller than I */,FIRST_OF,firstSmaller,<);
116  DEFINE_SEARCH(/*! Returns the position of the last element smaller than I */,LAST_OF,lastSmaller,<);
117 
118  DEFINE_SEARCH(/*! Returns the position of the first element larger than I */,FIRST_OF,firsLarger,>);
119  DEFINE_SEARCH(/*! Returns the position of the last element larger than I */,LAST_OF,lastLarger,>);
120 
121 #undef DEFINE_FIRST_OF
122 #undef DEFINE_LAST_OF
123 }
124 
125 #endif
#define LAST_OF
Constant used to parse last-occurrency case.
#define FIRST_OF
Constant used to parse first-occurrency case.
constexpr bool areOrderedAndDifferent
Returns true if all elements are weak ascending-ordered.
#define DEFINE_SEARCH(DESCRIPTION, FIRST_OR_LAST, NAME, COMPA)
Defines a searcher named NAME making the comparison COMPA with an external I.