SUNphi  1.0
Vector.hpp
Go to the documentation of this file.
1 #ifndef _VECTOR_HPP
2 #define _VECTOR_HPP
3 
4 /// \file Vector.hpp
5 ///
6 /// \brief Header file for the definition of vectors, and useful routines related
7 
8 #include <iostream>
9 #include <sstream>
10 
11 #include <functional>
12 #include <numeric>
13 #include <map>
14 #include <vector>
15 
16 #include <math/Arithmetic.hpp>
17 #include <metaprogramming/TypeTraits.hpp>
18 #include <metaprogramming/SFINAE.hpp>
19 #include <metaprogramming/UniversalReferences.hpp>
20 #include <utility/ScopeDoer.hpp>
21 
22 namespace SUNphi
23 {
24  /// Class wrapping std::vector
25  ///
26  /// Fix some some idiosinchrasy, such as the unsigned returned value
27  /// of size, and adds some useful method
28  template <typename T> // Type of objects inside the vector
29  class Vector :
30  public std::vector<T>
31  {
32  /// Type of the data returned by std::vector
33  using UnsignedSize=
34  typename std::vector<T>::size_type;
35 
36  public:
37 
38  /// Signed version of the std::vector<T> size
39  using Size=
41 
42  /// Returns the signed size
43  Size size() const
44  {
45  /// Gets the unsigned size
46  const UnsignedSize unsignedSize=
47  std::vector<T>::size();
48 
49  /// Converts to sign
50  return
51  static_cast<Size>(unsignedSize);
52  };
53 
54  /// Copy constructor
55  Vector(const Vector& oth) :
56  std::vector<T>(oth.begin(),oth.end())
57  {
58  }
59 
60  /// Forward constructor to std::vector
61  template <typename Arg,
62  typename...Args,
65  Args&&...args) :
66  std::vector<T>(forw<Arg>(arg),
67  forw<Args>(args)...)
68  {
69  }
70 
71  /// Default constructor
73  {
74  }
75 
76  /// Forward constrcution by initializing list
78  std::vector<T>(il)
79  {
80  }
81 
82  /// Computes the sum of all elements between \c [beg:end)
83  T summatorial(const UnsignedSize beg, ///< Begin
84  const UnsignedSize end) ///< End
85  const
86  {
87  return
88  std::accumulate(&(*this)[beg],&(*this)[end],T{0});
89  }
90 
91  /// Computes the sum of all elements between \c [beg:end)
92  ///
93  /// Case in which one only or no extreme is provided
94  T summatorial(const UnsignedSize beg=0) ///< Begin
95  const
96  {
97  return
98  summatorial(beg,size());
99  }
100 
101  /// Computes the product of all elements between \c [beg:end)
102  T productorial(const UnsignedSize beg, ///< Begin
103  const UnsignedSize end) ///< End
104  const
105  {
106  return
107  std::accumulate(&(*this)[beg],&(*this)[end],T{1},std::multiplies<T>());
108  }
109 
110  /// Computes the product of all elements between \c [beg:end)
111  ///
112  /// Case in which one only or no extreme is provided
113  T productorial(const UnsignedSize beg=0) ///< Begin
114  const
115  {
116  return
117  productorial(beg,size());
118  }
119 
120  /// Null action
121  static auto getNullAction()
122  {
123  return
124  [](const Vector<T>& v,Size pos){};
125  }
126 
127  /// True condition
128  static auto getTrueCondition()
129  {
130  return
131  [](const Vector<T>& v,Size pos){return true;};
132  }
133 
134  /// Returns an operator acting on a given element
135  template <typename F>
136  static auto getActer(F f)
137  {
138  return
139  [f](const Vector<T>& v,Size pos) mutable
140  {
141  return
142  f(v,pos);
143  };
144  }
145 
146  /// Returns an operator comparing and returning Ret when occurring, !Ret if not
147  template <bool Ret=true> // Returned value
148  static auto getComparer(const T& val) ///< Value to compare
149  {
150  return
151  getActer([val](const Vector<T>& v,Size pos) mutable
152  {
153  if(v[pos]==val)
154  return
155  Ret;
156  else
157  return
158  not Ret;
159  });
160  }
161 
162  /// Perform the action all elements starting from first up to last (excluded) or until the condition is true or false
163  ///
164  /// Returns the last position where the condition was true, or the
165  /// past-beyond delimiter if never occurred
166  template <bool falseTrue, /// Go on until the condition is false or true
167  typename C, /// Condition function type
168  typename A> /// Action to perform
169  Size loopUntil(const Size first, ///< First element to loop on
170  const Size last, ///< Last excluded element to loop on
171  C cond, ///< Condition function
172  A act) ///< Action to perform
173  const
174  {
175  /// Offset to move
176  const Size off=
177  sign(last-first);
178 
179  /// Position
180  Size pos=
181  first;
182 
183  // Loop
184  while(pos!=last and cond(*this,pos)==falseTrue)
185  {
186  act(*this,pos);
187  pos+=
188  off;
189  }
190 
191  return
192  pos;
193  }
194 
195  /// Finds the first element where the condition is false
196  template <typename C>
197  Size findFirstWhereNot(C cond) ///< Condition to check
198  const
199  {
200  return
201  loopUntil<true>(0,size(),cond,getNullAction());
202  }
203 
204  /// Finds the last element where the condition is false
205  template <typename C>
206  Size findLastWhereNot(C cond) ///< Condition to check
207  const
208  {
209  return
210  loopUntil<false>(size()-1,-1,cond,getNullAction());
211  }
212 
213  /// Finds the first element \c val
214  Size findFirst(const T& val) ///< Element to find
215  const
216  {
217  return
218  loopUntil<false>(0,size(),getComparer(val),getNullAction());
219  }
220 
221  /// Finds the first element different from \c val
222  Size findFirstDiffFrom(const T& val) ///< Element to find
223  const
224  {
225  return
227  }
228 
229  /// Finds the last element \c val
230  Size findLast(const T& val) ///< Element to find
231  const
232  {
233  return
234  loopUntil<false>(size()-1,-1,getComparer(val),getNullAction());
235  }
236 
237  /// Finds the last element different from \c val
238  Size findLastDiffFrom(const T& val) ///< Element to find
239  const
240  {
241  return
243  }
244 
245  /// Check if the value is contained
246  bool isContained(const T& val)
247  const
248  {
249  return
250  findFirst(val)!=size();
251  }
252 
253  /// Push back a value and pop it back when going out of scope
254  [[ nodiscard ]] auto scopePushBack(const T& val)
255  {
256  this->push_back(val);
257 
258  return
259  ScopeDoer([this](){this->pop_back();});
260  }
261 
262  /// Gets a string of form {1,2,3...}
264  const
265  {
266  /// Generator of the string
268 
269  // Open bracket
270  os<<"{";
271 
272  // First element
273  if(size())
274  os<<this->front();
275 
276  // Other elements
277  for(Size iEl=1;iEl<size();iEl++)
278  os<<","<<(*this)[iEl];
279 
280  // Close bracket
281  os<<"}";
282 
283  return
284  os.str();
285  }
286 
287  /// Group the vector returning a map
288  ///
289  /// Example
290  /// \code
291  ///
292  /// Vector v({2,2,3});
293  /// v.group(); // {{2,2},{3,1}}
294  /// \endcode
296  const
297  {
298  /// Result containing grouped factors
299  std::map<T,T> res;
300 
301  for(auto& f : *this)
302  res[f]++;
303 
304  return
305  res;
306  }
307 
308  /// Returns the result and remainder of the division
309  template <typename TOut>
310  void divWithMod(Vector<TOut>& quotient, ///< Result of the division
311  Vector<TOut>& remainder, ///< Remainder of the division
312  const Vector& divisor) ///< Divisor to be used
313  const
314  {
315  for(Size i=0;
316  i<this->size();
317  i++)
318  {
319  quotient[i]=
320  (*this)[i]/divisor[i];
321 
322  remainder[i]=
323  (*this)[i]%divisor[i];
324  }
325  }
326  };
327 
328  /// Gets first or second entry of the map
329  template <bool FirstSecond,
330  typename T1,
331  typename T2,
332  typename TOut=Conditional<FirstSecond,T2,T1>>
333  Vector<TOut> getAllFirstOrSecond(const std::map<T1,T2>& m)
334  {
335  /// Result
336  Vector<TOut> out;
337 
338  out.reserve(m.size());
339 
340  for(auto& it : m)
341  if constexpr(FirstSecond==true)
342  out.push_back(it.second);
343  else
344  out.push_back(it.first);
345 
346  return
347  out;
348  }
349 
350  /// Slice all keys of a map
351  template <typename T1,
352  typename T2>
353  auto getAllKeys(const std::map<T1,T2>& m)
354  {
355  return
356  getAllFirstOrSecond<false>(m);
357  }
358 
359  /// Slice all values of a map
360  template <typename T1,
361  typename T2>
362  auto getAllVal(const std::map<T1,T2>& m)
363  {
364  return
365  getAllFirstOrSecond<true>(m);
366  }
367 }
368 
369 #endif
Vector< TOut > getAllFirstOrSecond(const std::map< T1, T2 > &m)
Gets first or second entry of the map.
Definition: Vector.hpp:333
auto getAllKeys(const std::map< T1, T2 > &m)
Slice all keys of a map.
Definition: Vector.hpp:353
void divWithMod(Vector< TOut > &quotient, Vector< TOut > &remainder, const Vector &divisor) const
Returns the result and remainder of the division.
Definition: Vector.hpp:310
auto getAllVal(const std::map< T1, T2 > &m)
Slice all values of a map.
Definition: Vector.hpp:362
#define SFINAE_ON_TEMPLATE_ARG(...)
Definition: SFINAE.hpp:24
Size size() const
Returns the signed size.
Definition: Vector.hpp:43
Vector(const Vector &oth)
Copy constructor.
Definition: Vector.hpp:55