HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_FixedVector.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_FixedVector.h (UT Library, C++)
7  *
8  * COMMENTS: A vector class templated on its size and data type.
9  */
10 
11 #pragma once
12 
13 #ifndef __UT_FixedVector__
14 #define __UT_FixedVector__
15 
16 #include "UT_Assert.h"
17 #include "UT_Storage.h"
18 #include <SYS/SYS_Inline.h>
19 #include <SYS/SYS_Math.h>
20 #include <SYS/SYS_Types.h>
21 #include <SYS/SYS_TypeTraits.h>
22 
23 // Constructor Tags for UT_FixedVector
25 {
26  static constexpr struct ComponentFormType{} CF{};
27 };
28 
29 template<typename T,exint SIZE,bool INSTANTIATED=false>
31 {
32 public:
33  typedef T value_type;
34  static constexpr exint theSize = SIZE;
35 
36  using MF = typename UT_StorageNum<T>::MathFloat;
37 
38  SYS_FORCE_INLINE UT_FixedVector() = default;
39 
40  /// Initializes every component to the same value
41  constexpr explicit SYS_FORCE_INLINE UT_FixedVector(const T that) noexcept :
42  vec{}
43  {
44  for (exint i = 0; i < SIZE; ++i)
45  vec[i] = that;
46  }
47 
48  SYS_FORCE_INLINE UT_FixedVector(const UT_FixedVector &that) = default;
50 
51  /// Converts vector of S into vector of T,
52  /// or just copies if same type.
53  template<typename S,bool S_INSTANTIATED>
55  {
56  for (exint i = 0; i < SIZE; ++i)
57  vec[i] = that[i];
58  }
59 
60  template<typename S>
61  constexpr SYS_FORCE_INLINE UT_FixedVector(const S that[SIZE]) noexcept
62  {
63  for (exint i = 0; i < SIZE; ++i)
64  vec[i] = that[i];
65  }
66 
67  constexpr SYS_FORCE_INLINE const T &operator[](exint i) const noexcept
68  {
69  UT_ASSERT_EXPR_P(i >= 0 && i < SIZE);
70 
71  return vec[i];
72  }
73 
74  constexpr SYS_FORCE_INLINE T &operator[](exint i) noexcept
75  {
76  UT_ASSERT_EXPR_P(i >= 0 && i < SIZE);
77 
78  return vec[i];
79  }
80 
81  constexpr SYS_FORCE_INLINE const T* data() const noexcept
82  {
83  return vec;
84  }
85 
86  constexpr SYS_FORCE_INLINE T* data() noexcept
87  {
88  return vec;
89  }
90 
91  constexpr SYS_FORCE_INLINE UT_FixedVector& operator=(const UT_FixedVector &that) = default;
92  constexpr SYS_FORCE_INLINE UT_FixedVector& operator=(UT_FixedVector &&that) = default;
93 
94  template <typename S,bool S_INSTANTIATED>
96  {
97  for (exint i = 0; i < SIZE; ++i)
98  vec[i] = that[i];
99  return *this;
100  }
101  constexpr SYS_FORCE_INLINE const UT_FixedVector &operator=(T that) noexcept
102  {
103  for (exint i = 0; i < SIZE; ++i)
104  vec[i] = that;
105  return *this;
106  }
107  template<typename S,bool S_INSTANTIATED>
109  {
110  for (exint i = 0; i < SIZE; ++i)
111  vec[i] += that[i];
112  }
113  constexpr SYS_FORCE_INLINE void operator+=(T that) noexcept
114  {
115  for (exint i = 0; i < SIZE; ++i)
116  vec[i] += that;
117  }
118  template<typename S,bool S_INSTANTIATED>
120  {
121  typedef typename UT_StorageBetter<T,S>::Type Type;
123  for (exint i = 0; i < SIZE; ++i)
124  result[i] = vec[i] + that[i];
125  return result;
126  }
127  template<typename S,bool S_INSTANTIATED>
129  {
130  for (exint i = 0; i < SIZE; ++i)
131  vec[i] -= that[i];
132  }
133  constexpr SYS_FORCE_INLINE void operator-=(T that) noexcept
134  {
135  for (exint i = 0; i < SIZE; ++i)
136  vec[i] -= that;
137  }
138  template<typename S,bool S_INSTANTIATED>
140  {
141  typedef typename UT_StorageBetter<T,S>::Type Type;
143  for (exint i = 0; i < SIZE; ++i)
144  result[i] = vec[i] - that[i];
145  return result;
146  }
147  template<typename S,bool S_INSTANTIATED>
149  {
150  for (exint i = 0; i < SIZE; ++i)
151  vec[i] *= that[i];
152  }
153  template<typename S,bool S_INSTANTIATED>
155  {
156  typedef typename UT_StorageBetter<T,S>::Type Type;
158  for (exint i = 0; i < SIZE; ++i)
159  result[i] = vec[i] * that[i];
160  return result;
161  }
162  constexpr SYS_FORCE_INLINE void operator*=(T that) noexcept
163  {
164  for (exint i = 0; i < SIZE; ++i)
165  vec[i] *= that;
166  }
167  /// NOTE: Strictly speaking, this should use UT_StorageBetter<T,S>::Type,
168  /// but in the interests of avoiding accidental precision escalation,
169  /// it uses T.
170  constexpr SYS_FORCE_INLINE UT_FixedVector<T,SIZE> operator*(T that) const noexcept
171  {
173  for (exint i = 0; i < SIZE; ++i)
174  result[i] = vec[i] * that;
175  return result;
176  }
177  template<typename S,bool S_INSTANTIATED>
179  {
180  for (exint i = 0; i < SIZE; ++i)
181  vec[i] /= that[i];
182  }
183  template<typename S,bool S_INSTANTIATED>
185  {
186  typedef typename UT_StorageBetter<T,S>::Type Type;
188  for (exint i = 0; i < SIZE; ++i)
189  result[i] = vec[i] / that[i];
190  return result;
191  }
192 
193  constexpr SYS_FORCE_INLINE void operator/=(T that) noexcept
194  {
195  MF t(that);
196  t = MF(1)/t;
197  for (exint i = 0; i < SIZE; ++i)
198  vec[i] *= t;
199  }
200  /// NOTE: Strictly speaking, this should use UT_StorageBetter<T,S>::Type,
201  /// but in the interests of avoiding accidental precision escalation,
202  /// it uses T.
203  constexpr SYS_FORCE_INLINE UT_FixedVector<T,SIZE> operator/(T that) const noexcept
204  {
205  MF t(that);
206  t = MF(1)/t;
208  for (exint i = 0; i < SIZE; ++i)
209  result[i] = vec[i] * t;
210  return result;
211  }
212  constexpr SYS_FORCE_INLINE void negate() noexcept
213  {
214  for (exint i = 0; i < SIZE; ++i)
215  vec[i] = -vec[i];
216  }
217 
219  {
221  for (exint i = 0; i < SIZE; ++i)
222  result[i] = -vec[i];
223  return result;
224  }
225 
226  template<typename S,bool S_INSTANTIATED>
227  constexpr SYS_FORCE_INLINE bool operator==(const UT_FixedVector<S,SIZE,S_INSTANTIATED> &that) const noexcept
228  {
229  for (exint i = 0; i < SIZE; ++i)
230  {
231  if (vec[i] != T(that[i]))
232  return false;
233  }
234  return true;
235  }
236  template<typename S,bool S_INSTANTIATED>
237  constexpr SYS_FORCE_INLINE bool operator!=(const UT_FixedVector<S,SIZE,S_INSTANTIATED> &that) const noexcept
238  {
239  return !(*this==that);
240  }
241  /// Lexicographic order comparison operators
242  /// @{
243  template<typename S,bool S_INSTANTIATED>
244  constexpr SYS_FORCE_INLINE bool operator<(const UT_FixedVector<S,SIZE,S_INSTANTIATED> &that) const noexcept
245  {
246  for (exint i = 0; i < SIZE-1; ++i)
247  {
248  if (vec[i] != that[i])
249  return (vec[i] < that[i]);
250  }
251  return (vec[SIZE-1] < that[SIZE-1]);
252  }
253  template<typename S,bool S_INSTANTIATED>
254  constexpr SYS_FORCE_INLINE bool operator<=(const UT_FixedVector<S,SIZE,S_INSTANTIATED> &that) const noexcept
255  {
256  for (exint i = 0; i < SIZE-1; ++i)
257  {
258  if (vec[i] != that[i])
259  return (vec[i] < that[i]);
260  }
261  return (vec[SIZE-1] <= that[SIZE-1]);
262  }
263  template<typename S,bool S_INSTANTIATED>
264  constexpr SYS_FORCE_INLINE bool operator>(const UT_FixedVector<S,SIZE,S_INSTANTIATED> &that) const noexcept
265  {
266  // NOTE: Because of NaNs, this can't just be !(*this <= that)
267  for (exint i = 0; i < SIZE-1; ++i)
268  {
269  if (vec[i] != that[i])
270  return (vec[i] > that[i]);
271  }
272  return (vec[SIZE-1] > that[SIZE-1]);
273  }
274  template<typename S,bool S_INSTANTIATED>
275  constexpr SYS_FORCE_INLINE bool operator>=(const UT_FixedVector<S,SIZE,S_INSTANTIATED> &that) const noexcept
276  {
277  // NOTE: Because of NaNs, this can't just be !(*this < that)
278  for (exint i = 0; i < SIZE-1; ++i)
279  {
280  if (vec[i] != that[i])
281  return (vec[i] > that[i]);
282  }
283  return (vec[SIZE-1] >= that[SIZE-1]);
284  }
285  /// @}
286  SYS_FORCE_INLINE bool isNan() const
287  {
288  for (exint i = 0; i < SIZE; ++i)
289  {
290  if (SYSisNan(vec[i]))
291  return true;
292  }
293  return false;
294  }
296  {
297  for (exint i = 0; i < SIZE; ++i)
298  {
299  if (!SYSisFinite(vec[i]))
300  return false;
301  }
302  return true;
303  }
304  SYS_FORCE_INLINE bool isZero() const noexcept
305  {
306  for (exint i = 0; i < SIZE; ++i)
307  {
308  if (vec[i] != T(0))
309  return false;
310  }
311  return true;
312  }
314  {
315  for (exint i = 0; i < SIZE; ++i)
316  {
317  // NB: We return FALSE for NaN values
318  if (!(vec[i] >= -tol) || !(vec[i] <= tol))
319  return false;
320  }
321  return true;
322  }
323  template<typename S,bool S_INSTANTIATED>
325  {
326  for (exint i = 0; i < SIZE; ++i)
327  {
328  // NB: We return FALSE for NaN values
329  if (!(vec[i] >= that[i]-tol) || !(vec[i] <= that[i]+tol))
330  return false;
331  }
332  return true;
333  }
335  {
336  T v = vec[0];
337  for (exint i = 1; i < SIZE; ++i)
338  v = (vec[i] > v) ? vec[i] : v;
339  return v;
340  }
342  {
343  T v = vec[0];
344  for (exint i = 1; i < SIZE; ++i)
345  v = (vec[i] < v) ? vec[i] : v;
346  return v;
347  }
349  {
350  T v = vec[0];
351  for (exint i = 1; i < SIZE; ++i)
352  v += vec[i];
353  return v / SIZE;
354  }
355 
357  {
358  typedef typename UT_StorageAtLeast32Bit<T,T>::Type TheType;
359  TheType a0(vec[0]);
360  TheType result(a0*a0);
361  for (exint i = 1; i < SIZE; ++i)
362  {
363  TheType ai(vec[i]);
364  result += ai*ai;
365  }
366  return result;
367  }
369  {
370  MF len2(length2());
371  return SYSsqrt(len2);
372  }
373  template<typename S,bool S_INSTANTIATED>
375  {
376  typedef typename UT_StorageAtLeast32Bit<T,S>::Type TheType;
377  TheType result(TheType(vec[0])*TheType(that[0]));
378  for (exint i = 1; i < SIZE; ++i)
379  result += TheType(vec[i])*TheType(that[i]);
380  return result;
381  }
382  template<typename S,bool S_INSTANTIATED>
384  {
385  typedef typename UT_StorageAtLeast32Bit<T,S>::Type TheType;
386  TheType v(TheType(vec[0]) - TheType(that[0]));
387  TheType result(v*v);
388  for (exint i = 1; i < SIZE; ++i)
389  {
390  v = TheType(vec[i]) - TheType(that[i]);
391  result += v*v;
392  }
393  return result;
394  }
395  template<typename S,bool S_INSTANTIATED>
397  {
398  typename UT_StorageNum<typename UT_StorageBetter<T,S>::Type>::MathFloat dist2(distance2(that));
399  return SYSsqrt(dist2);
400  }
401 
403  {
404  typename Storage::AtLeast32Bit len2 = length2();
406  return typename Storage::MathFloat(0);
407  if (len2 == typename Storage::AtLeast32Bit(1))
408  return typename Storage::MathFloat(1);
409  typename Storage::MathFloat len = SYSsqrt(typename Storage::MathFloat(len2));
410  // Check if the square root is equal 1. sqrt(1+dx) ~ 1+dx/2,
411  // so it may get rounded to 1 when it wasn't 1 before.
412  if (len != typename Storage::MathFloat(1))
413  (*this) /= len;
414  return len;
415  }
416 
417 protected:
419 
420  template< typename... AS >
421  constexpr UT_FixedVector(const CT::ComponentFormType, const AS... as) noexcept :
422  vec{ as... }
423  {
424  SYS_STATIC_ASSERT( sizeof...( as ) == SIZE );
425  }
426 private:
427  using Storage = UT_StorageNum<T>;
428 
429 public:
431 };
432 
433 /// NOTE: Strictly speaking, this should use UT_StorageBetter<T,S>::Type,
434 /// but in the interests of avoiding accidental precision escalation,
435 /// it uses T.
436 template<typename T,exint SIZE,bool INSTANTIATED,typename S>
438 {
439  T t(that);
441  for (exint i = 0; i < SIZE; ++i)
442  result[i] = t * a[i];
443  return result;
444 }
445 
446 template<typename T, exint SIZE, bool INSTANTIATED, typename S, bool S_INSTANTIATED>
449 {
450  return a.dot(b);
451 }
452 
453 template<typename T>
455 {
457  typedef T DataType;
458  static const exint TupleSize = 1;
459  static const bool isVectorType = false;
460 };
461 
462 template<typename T,exint SIZE,bool INSTANTIATED>
464 {
466  typedef T DataType;
467  static const exint TupleSize = SIZE;
468  static const bool isVectorType = true;
469 };
470 
471 #endif
SYS_FORCE_INLINE T minComponent() const
constexpr UT_FixedVector(const CT::ComponentFormType, const AS...as) noexcept
Mat3< typename promote< S, T >::type > operator*(S scalar, const Mat3< T > &m)
Multiply each element of the given matrix by scalar and return the result.
Definition: Mat3.h:575
constexpr SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator-() const noexcept
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
#define SYS_STATIC_ASSERT(expr)
SYS_FORCE_INLINE bool isNan() const
constexpr SYS_FORCE_INLINE UT_FixedVector & operator=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
constexpr SYS_FORCE_INLINE bool operator>(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
SYS_FORCE_INLINE bool equalZero(T tol=T(SYS_FTOLERANCE)) const
SYS_FORCE_INLINE bool isZero() const noexcept
bool SYSisFinite(fpreal64 f)
Definition: SYS_Math.h:194
UT_FixedVector< T, SIZE, INSTANTIATED > FixedVectorType
int64 exint
Definition: SYS_Types.h:125
void AtLeast32Bit
Definition: UT_Storage.h:88
constexpr bool SYSisNan(const F f)
Definition: SYS_Math.h:178
SYS_FORCE_INLINE MF length() const
static const exint TupleSize
constexpr SYS_FORCE_INLINE void operator/=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
GLdouble GLdouble t
Definition: glew.h:1403
constexpr SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator*(T that) const noexcept
constexpr SYS_FORCE_INLINE void operator*=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
constexpr SYS_FORCE_INLINE void operator-=(T that) noexcept
SYS_FORCE_INLINE UT_FixedVector()=default
constexpr SYS_FORCE_INLINE void operator+=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
constexpr SYS_FORCE_INLINE T * data() noexcept
SYS_FORCE_INLINE MF normalize()
SYS_FORCE_INLINE UT_FixedVector(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
SYS_FORCE_INLINE bool isFinite() const
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
constexpr SYS_FORCE_INLINE void operator/=(T that) noexcept
fpreal32 MathFloat
Definition: UT_Storage.h:89
constexpr SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator*(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
static constexpr struct UT_FixedVectorCT::ComponentFormType CF
GLenum GLsizei len
Definition: glew.h:7782
constexpr SYS_FORCE_INLINE void operator*=(T that) noexcept
const GLdouble * v
Definition: glcorearb.h:836
static const bool isVectorType
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
SYS_FORCE_INLINE UT_StorageAtLeast32Bit< T, S >::Type distance2(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
constexpr SYS_FORCE_INLINE UT_FixedVector(const S that[SIZE]) noexcept
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
constexpr SYS_FORCE_INLINE UT_FixedVector(const T that) noexcept
Initializes every component to the same value.
SYS_FORCE_INLINE T maxComponent() const
constexpr SYS_FORCE_INLINE UT_FixedVector & operator=(const UT_FixedVector &that)=default
#define UT_ASSERT_EXPR_P(ZZ)
Definition: UT_Assert.h:167
constexpr SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator+(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
SYS_FORCE_INLINE UT_StorageNum< typename UT_StorageBetter< T, S >::Type >::MathFloat distance(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
constexpr SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator-(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
constexpr SYS_FORCE_INLINE const UT_FixedVector & operator=(T that) noexcept
constexpr SYS_FORCE_INLINE bool operator==(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
constexpr SYS_FORCE_INLINE void operator+=(T that) noexcept
constexpr SYS_FORCE_INLINE UT_StorageAtLeast32Bit< T, T >::Type length2() const noexcept
SYS_FORCE_INLINE UT_StorageAtLeast32Bit< T, S >::Type dot(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const
typename SYS_SelectType< typename UT_StorageNum< typename UT_StorageBetter< T0, T1 >::Type >::AtLeast32Bit, T0, UT_StorageNum< typename UT_StorageBetter< T0, T1 >::Type >::theStorage==UT_Storage::INVALID >::type Type
Definition: UT_Storage.h:254
constexpr SYS_FORCE_INLINE const T * data() const noexcept
static constexpr exint theSize
SYS_FORCE_INLINE bool isEqual(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that, S tol=S(SYS_FTOLERANCE)) const
UT_FixedVector< T, 1 > FixedVectorType
SYS_FORCE_INLINE UT_StorageAtLeast32Bit< T, S >::Type dot(const UT_FixedVector< T, SIZE, INSTANTIATED > &a, const UT_FixedVector< S, SIZE, S_INSTANTIATED > &b)
constexpr SYS_FORCE_INLINE void operator-=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) noexcept
typename UT_StorageNum< T >::MathFloat MF
#define SIZE
Definition: simple.C:40
#define SYS_FTOLERANCE
Definition: SYS_Types.h:208
#define const
Definition: zconf.h:214
constexpr SYS_FORCE_INLINE void negate() noexcept
SYS_FORCE_INLINE T avgComponent() const
constexpr SYS_FORCE_INLINE bool operator>=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
constexpr SYS_FORCE_INLINE bool operator!=(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
constexpr SYS_FORCE_INLINE const T & operator[](exint i) const noexcept
constexpr SYS_FORCE_INLINE UT_FixedVector< typename UT_StorageBetter< T, S >::Type, SIZE > operator/(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that) const noexcept
constexpr SYS_FORCE_INLINE UT_FixedVector< T, SIZE > operator/(T that) const noexcept
constexpr SYS_FORCE_INLINE T & operator[](exint i) noexcept