OpenVDB  8.1.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 //
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 
23 struct Conversion {};
24 
25 
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  Tuple() = default;
42 #else
43  Tuple() {}
47 
49  Tuple(Tuple const& src) {
50  for (int i = 0; i < SIZE; ++i) {
51  mm[i] = src.mm[i];
52  }
53  }
54 
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 
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 
103 
104  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 
114  return mm;
115  }
117  value_type const *asV() const {
118  return mm;
119  }
121 
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 
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 
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 
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 
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 
184 
185 
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 
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 
211 
212 
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 
224 template<int SIZE, typename T>
225 inline bool isNan(const Tuple<SIZE, T>& t) { return t.isNan(); }
226 
228 template<int SIZE, typename T>
229 inline bool isInfinite(const Tuple<SIZE, T>& t) { return t.isInfinite(); }
230 
232 template<int SIZE, typename T>
233 inline bool isFinite(const Tuple<SIZE, T>& t) { return t.isFinite(); }
234 
236 template<int SIZE, typename T>
237 inline bool isZero(const Tuple<SIZE, T>& t) { return t.isZero(); }
238 
240 
241 
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 mm[SIZE]
Definition: Tuple.h:179
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
bool isNan(const Tuple< SIZE, T > &t)
Return true if a Nan is present in the tuple.
Definition: Tuple.h:225
bool isInfinite(const Tuple< SIZE, T > &t)
Return true if an Inf is present in the tuple.
Definition: Tuple.h:229
void toV(S *v) const
Copies this tuple into an array of a compatible type.
Definition: Tuple.h:106
value_type * asV()
Exposes the internal array. Be careful when using this function.
Definition: Tuple.h:113
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
bool isFinite() const
True if no Nan or Inf values are present.
Definition: Tuple.h:163
bool isZero(const Tuple< SIZE, T > &t)
Return true if all elements are exactly equal to zero.
Definition: Tuple.h:237
bool isNan() const
True if a Nan is present in this tuple.
Definition: Tuple.h:147
Tuple< SIZE, T > Abs(const Tuple< SIZE, T > &t)
Definition: Tuple.h:216
bool isFinite(const Tuple< SIZE, T > &t)
Return true if no Nan or Inf values are present.
Definition: Tuple.h:233
T value_type
Definition: Tuple.h:32
value_type const * asV() const
Exposes the internal array. Be careful when using this function.
Definition: Tuple.h:117
Definition: openvdb/Exceptions.h:13
Definition: Tuple.h:29
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
Dummy class for tag dispatch of conversion constructors.
Definition: Tuple.h:23
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
void read(std::istream &is)
Definition: Tuple.h:142
T operator[](int i) const
Definition: Tuple.h:86
std::string str() const
Definition: Tuple.h:123
T ValueType
Definition: Tuple.h:33
void write(std::ostream &os) const
Definition: Tuple.h:139
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
Tuple(Tuple< src_size, src_valtype > const &src)
Conversion constructor.
Definition: Tuple.h:75
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:178
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:201
T & operator[](int i)
Definition: Tuple.h:94