OpenVDB  9.0.1
Tuple.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @file Tuple.h
5 /// @author Ben Kwa
6 
7 #ifndef OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
8 #define OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
9 
10 #include "Math.h"
11 #include <cmath>
12 #include <sstream>
13 #include <string>
14 #include <type_traits>
15 
16 
17 namespace openvdb {
19 namespace OPENVDB_VERSION_NAME {
20 namespace math {
21 
22 /// @brief Dummy class for tag dispatch of conversion constructors
23 struct Conversion {};
24 
25 
26 /// @class Tuple "Tuple.h"
27 /// A base class for homogenous tuple types
28 template<int SIZE, typename T>
29 class Tuple
30 {
31 public:
32  using value_type = T;
33  using ValueType = T;
34 
35  static const int size = SIZE;
36 
37 #if OPENVDB_ABI_VERSION_NUMBER >= 8
38  /// Trivial constructor, the Tuple is NOT initialized
39  /// @note destructor, copy constructor, assignment operator and
40  /// move constructor are left to be defined by the compiler (default)
41  Tuple() = default;
42 #else
43  /// @brief Default ctor. Does nothing.
44  /// @details This is required because declaring a copy (or other) constructor
45  /// prevents the compiler from synthesizing a default constructor.
46  Tuple() {}
47 
48  /// Copy constructor. Used when the class signature matches exactly.
49  Tuple(Tuple const& src) {
50  for (int i = 0; i < SIZE; ++i) {
51  mm[i] = src.mm[i];
52  }
53  }
54 
55  /// @brief Assignment operator
56  /// @details This is required because declaring a copy (or other) constructor
57  /// prevents the compiler from synthesizing a default assignment operator.
58  Tuple& operator=(Tuple const& src) {
59  if (&src != this) {
60  for (int i = 0; i < SIZE; ++i) {
61  mm[i] = src.mm[i];
62  }
63  }
64  return *this;
65  }
66 #endif
67 
68  /// @brief Conversion constructor.
69  /// @details Tuples with different value types and different sizes can be
70  /// interconverted using this member. Converting from a larger tuple
71  /// results in truncation; converting from a smaller tuple results in
72  /// the extra data members being zeroed out. This function assumes that
73  /// the integer 0 is convertible to the tuple's value type.
74  template <int src_size, typename src_valtype>
75  explicit Tuple(Tuple<src_size, src_valtype> const &src) {
76  enum { COPY_END = (SIZE < src_size ? SIZE : src_size) };
77 
78  for (int i = 0; i < COPY_END; ++i) {
79  mm[i] = src[i];
80  }
81  for (int i = COPY_END; i < SIZE; ++i) {
82  mm[i] = 0;
83  }
84  }
85 
86  T operator[](int i) const {
87  // we'd prefer to use size_t, but can't because gcc3.2 doesn't like
88  // it - it conflicts with child class conversion operators to
89  // pointer types.
90 // assert(i >= 0 && i < SIZE);
91  return mm[i];
92  }
93 
94  T& operator[](int i) {
95  // see above for size_t vs int
96 // assert(i >= 0 && i < SIZE);
97  return mm[i];
98  }
99 
100  /// @name Compatibility
101  /// These are mostly for backwards compability with functions that take
102  /// old-style Vs (which are just arrays).
103  //@{
104  /// Copies this tuple into an array of a compatible type
105  template <typename S>
106  void toV(S *v) const {
107  for (int i = 0; i < SIZE; ++i) {
108  v[i] = mm[i];
109  }
110  }
111 
112  /// Exposes the internal array. Be careful when using this function.
114  return mm;
115  }
116  /// Exposes the internal array. Be careful when using this function.
117  value_type const *asV() const {
118  return mm;
119  }
120  //@} Compatibility
121 
122  /// @return string representation of Classname
123  std::string str() const {
124  std::ostringstream buffer;
125 
126  buffer << "[";
127 
128  // For each column
129  for (unsigned j(0); j < SIZE; j++) {
130  if (j) buffer << ", ";
131  buffer << PrintCast(mm[j]);
132  }
133 
134  buffer << "]";
135 
136  return buffer.str();
137  }
138 
139  void write(std::ostream& os) const {
140  os.write(reinterpret_cast<const char*>(&mm), sizeof(T)*SIZE);
141  }
142  void read(std::istream& is) {
143  is.read(reinterpret_cast<char*>(&mm), sizeof(T)*SIZE);
144  }
145 
146  /// True if a Nan is present in this tuple
147  bool isNan() const {
148  for (int i = 0; i < SIZE; ++i) {
149  if (math::isNan(mm[i])) return true;
150  }
151  return false;
152  }
153 
154  /// True if an Inf is present in this tuple
155  bool isInfinite() const {
156  for (int i = 0; i < SIZE; ++i) {
157  if (math::isInfinite(mm[i])) return true;
158  }
159  return false;
160  }
161 
162  /// True if no Nan or Inf values are present
163  bool isFinite() const {
164  for (int i = 0; i < SIZE; ++i) {
165  if (!math::isFinite(mm[i])) return false;
166  }
167  return true;
168  }
169 
170  /// True if all elements are exactly zero
171  bool isZero() const {
172  for (int i = 0; i < SIZE; ++i) {
173  if (!math::isZero(mm[i])) return false;
174  }
175  return true;
176  }
177 
178 protected:
179  T mm[SIZE];
180 };
181 
182 
183 ////////////////////////////////////////
184 
185 
186 /// @return true if t0 < t1, comparing components in order of significance.
187 template<int SIZE, typename T0, typename T1>
188 bool
189 operator<(const Tuple<SIZE, T0>& t0, const Tuple<SIZE, T1>& t1)
190 {
191  for (int i = 0; i < SIZE-1; ++i) {
192  if (!isExactlyEqual(t0[i], t1[i])) return t0[i] < t1[i];
193  }
194  return t0[SIZE-1] < t1[SIZE-1];
195 }
196 
197 
198 /// @return true if t0 > t1, comparing components in order of significance.
199 template<int SIZE, typename T0, typename T1>
200 bool
202 {
203  for (int i = 0; i < SIZE-1; ++i) {
204  if (!isExactlyEqual(t0[i], t1[i])) return t0[i] > t1[i];
205  }
206  return t0[SIZE-1] > t1[SIZE-1];
207 }
208 
209 
210 ////////////////////////////////////////
211 
212 
213 /// @return the absolute value of the given Tuple.
214 template<int SIZE, typename T>
217 {
218  Tuple<SIZE, T> result;
219  for (int i = 0; i < SIZE; ++i) result[i] = math::Abs(t[i]);
220  return result;
221 }
222 
223 /// Return @c true if a Nan is present in the tuple.
224 template<int SIZE, typename T>
225 inline bool isNan(const Tuple<SIZE, T>& t) { return t.isNan(); }
226 
227 /// Return @c true if an Inf is present in the tuple.
228 template<int SIZE, typename T>
229 inline bool isInfinite(const Tuple<SIZE, T>& t) { return t.isInfinite(); }
230 
231 /// Return @c true if no Nan or Inf values are present.
232 template<int SIZE, typename T>
233 inline bool isFinite(const Tuple<SIZE, T>& t) { return t.isFinite(); }
234 
235 /// Return @c true if all elements are exactly equal to zero.
236 template<int SIZE, typename T>
237 inline bool isZero(const Tuple<SIZE, T>& t) { return t.isZero(); }
238 
239 ////////////////////////////////////////
240 
241 
242 /// Write a Tuple to an output stream
243 template <int SIZE, typename T>
244 std::ostream& operator<<(std::ostream& ostr, const Tuple<SIZE, T>& classname)
245 {
246  ostr << classname.str();
247  return ostr;
248 }
249 
250 } // namespace math
251 } // namespace OPENVDB_VERSION_NAME
252 } // namespace openvdb
253 
254 #endif // OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
T ValueType
Definition: Tuple.h:33
bool isNan() const
True if a Nan is present in this tuple.
Definition: Tuple.h:147
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
Definition: Tuple.h:29
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Tuple(Tuple< src_size, src_valtype > const &src)
Conversion constructor.
Definition: Tuple.h:75
void write(std::ostream &os) const
Definition: Tuple.h:139
T & operator[](int i)
Definition: Tuple.h:94
void read(std::istream &is)
Definition: Tuple.h:142
value_type * asV()
Exposes the internal array. Be careful when using this function.
Definition: Tuple.h:113
bool isNan(const Tuple< SIZE, T > &t)
Return true if a Nan is present in the tuple.
Definition: Tuple.h:225
void toV(S *v) const
Copies this tuple into an array of a compatible type.
Definition: Tuple.h:106
std::string str() const
Definition: Tuple.h:123
bool isFinite() const
True if no Nan or Inf values are present.
Definition: Tuple.h:163
Dummy class for tag dispatch of conversion constructors.
Definition: Tuple.h:23
Definition: Exceptions.h:13
T mm[SIZE]
Definition: Tuple.h:179
value_type const * asV() const
Exposes the internal array. Be careful when using this function.
Definition: Tuple.h:117
bool isZero(const Tuple< SIZE, T > &t)
Return true if all elements are exactly equal to zero.
Definition: Tuple.h:237
Tuple< SIZE, T > Abs(const Tuple< SIZE, T > &t)
Definition: Tuple.h:216
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:201
auto PrintCast(const T &val) -> typename std::enable_if<!std::is_same< T, int8_t >::value &&!std::is_same< T, uint8_t >::value, const T & >::type
8-bit integer values print to std::ostreams as characters. Cast them so that they print as integers i...
Definition: Math.h:885
bool isInfinite(const Tuple< SIZE, T > &t)
Return true if an Inf is present in the tuple.
Definition: Tuple.h:229
bool isInfinite() const
True if an Inf is present in this tuple.
Definition: Tuple.h:155
bool isZero() const
True if all elements are exactly zero.
Definition: Tuple.h:171
T operator[](int i) const
Definition: Tuple.h:86
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
T value_type
Definition: Tuple.h:32
bool isFinite(const Tuple< SIZE, T > &t)
Return true if no Nan or Inf values are present.
Definition: Tuple.h:233