OpenVDB 13.0.1
Loading...
Searching...
No Matches
Tuple.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-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 <openvdb/util/Assert.h>
12#include <cmath>
13#include <sstream>
14#include <string>
15#include <type_traits>
16
17
18namespace openvdb {
20namespace OPENVDB_VERSION_NAME {
21namespace math {
22
23/// @brief Dummy class for tag dispatch of conversion constructors
24struct Conversion {};
25
26
27/// @class Tuple "Tuple.h"
28/// A base class for homogenous tuple types
29template<int SIZE, typename T>
30class Tuple
31{
32public:
33 using value_type = T;
34 using ValueType = T;
35
36 static const int size = SIZE;
37
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
43 /// @brief Conversion constructor.
44 /// @details Tuples with different value types and different sizes can be
45 /// interconverted using this member. Converting from a larger tuple
46 /// results in truncation; converting from a smaller tuple results in
47 /// the extra data members being zeroed out. This function assumes that
48 /// the integer 0 is convertible to the tuple's value type.
49 template <int src_size, typename src_valtype>
50 explicit Tuple(Tuple<src_size, src_valtype> const &src) {
51 enum { COPY_END = (SIZE < src_size ? SIZE : src_size) };
52
53 for (int i = 0; i < COPY_END; ++i) {
54 mm[i] = src[i];
55 }
56 for (int i = COPY_END; i < SIZE; ++i) {
57 mm[i] = 0;
58 }
59 }
60
61 /// @brief Constructor that fills this tuple with a value
62 explicit Tuple(const T val) {
63 for (int i = 0; i < size; ++i) { mm[i] = val; }
64 }
65
66 // @brief const access to an element in the tuple. The offset idx must be
67 // an integral type. A copy of the tuple data is returned.
68 template <typename IdxT,
69 typename std::enable_if<std::is_integral<IdxT>::value, bool>::type = true>
70 T operator[](IdxT i) const {
71 OPENVDB_ASSERT(i >= IdxT(0) && i < IdxT(SIZE));
72 return mm[i];
73 }
74
75 // @brief non-const access to an element in the tuple. The offset idx must be
76 // an integral type. A reference to the tuple data is returned.
77 template <typename IdxT,
78 typename std::enable_if<std::is_integral<IdxT>::value, bool>::type = true>
79 T& operator[](IdxT i) {
80 OPENVDB_ASSERT(i >= IdxT(0) && i < IdxT(SIZE));
81 return mm[i];
82 }
83
84 // These exist solely to provide backwards compatibility with [] access of
85 // non-integer types that were castable to 'int' (such as floating point type).
86 // The above templates allow for any integer type to be used as an offset into
87 // the tuple data.
88 T operator[](int i) const { return this->template operator[]<int>(i); }
89 T& operator[](int i) { return this->template operator[]<int>(i); }
90
91 /// @name Compatibility
92 /// These are mostly for backwards compatibility with functions that take
93 /// old-style Vs (which are just arrays).
94 //@{
95 /// Copies this tuple into an array of a compatible type
96 template <typename S>
97 void toV(S *v) const {
98 for (int i = 0; i < SIZE; ++i) {
99 v[i] = mm[i];
100 }
101 }
102
103 /// Exposes the internal array. Be careful when using this function.
105 return mm;
106 }
107 /// Exposes the internal array. Be careful when using this function.
108 value_type const *asV() const {
109 return mm;
110 }
111 //@} Compatibility
112
113 ///////////////////////////////////////////////////////////////////////////
114
116 Tuple r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] + in[i]; return r;
117 }
119 Tuple r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] - in[i]; return r;
120 }
122 Tuple r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] * in[i]; return r;
123 }
125 Tuple r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] / in[i]; return r;
126 }
128 Tuple r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] & in[i]; return r;
129 }
131 Tuple r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] | in[i]; return r;
132 }
133
134 Tuple& operator+=(Tuple in) { for (int i = 0; i < SIZE; ++i) mm[i] += in[i]; return *this; }
135 Tuple& operator-=(Tuple in) { for (int i = 0; i < SIZE; ++i) mm[i] -= in[i]; return *this; }
136 Tuple& operator*=(Tuple in) { for (int i = 0; i < SIZE; ++i) mm[i] *= in[i]; return *this; }
137 Tuple& operator/=(Tuple in) { for (int i = 0; i < SIZE; ++i) mm[i] /= in[i]; return *this; }
138 Tuple& operator&=(Tuple in) { for (int i = 0; i < SIZE; ++i) mm[i] &= in[i]; return *this; }
139 Tuple& operator|=(Tuple in) { for (int i = 0; i < SIZE; ++i) mm[i] |= in[i]; return *this; }
140
142 Tuple<SIZE, bool> r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] >= in[i]; return r;
143 }
144 Tuple<SIZE, bool> operator<=(Tuple in) const {
145 Tuple<SIZE, bool> r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] <= in[i]; return r;
146 }
148 Tuple<SIZE, bool> r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] > in[i]; return r;
149 }
151 Tuple<SIZE, bool> r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] < in[i]; return r;
152 }
154 Tuple<SIZE, bool> r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] == in[i]; return r;
155 }
157 Tuple<SIZE, bool> r; for (int i = 0; i < SIZE; ++i) r[i] = mm[i] != in[i]; return r;
158 }
159
160 ///////////////////////////////////////////////////////////////////////////
161
162 /// @return string representation of Classname
163 std::string str() const {
164 std::ostringstream buffer;
165
166 buffer << "[";
167
168 // For each column
169 for (unsigned j(0); j < SIZE; j++) {
170 if (j) buffer << ", ";
171 buffer << PrintCast(mm[j]);
172 }
173
174 buffer << "]";
175
176 return buffer.str();
177 }
178
179 void write(std::ostream& os) const {
180 os.write(reinterpret_cast<const char*>(&mm), sizeof(T)*SIZE);
181 }
182 void read(std::istream& is) {
183 is.read(reinterpret_cast<char*>(&mm), sizeof(T)*SIZE);
184 }
185
186 /// True if a Nan is present in this tuple
187 bool isNan() const {
188 for (int i = 0; i < SIZE; ++i) {
189 if (math::isNan(mm[i])) return true;
190 }
191 return false;
192 }
193
194 /// True if an Inf is present in this tuple
195 bool isInfinite() const {
196 for (int i = 0; i < SIZE; ++i) {
197 if (math::isInfinite(mm[i])) return true;
198 }
199 return false;
200 }
201
202 /// True if no Nan or Inf values are present
203 bool isFinite() const {
204 for (int i = 0; i < SIZE; ++i) {
205 if (!math::isFinite(mm[i])) return false;
206 }
207 return true;
208 }
209
210 /// True if all elements are exactly zero
211 bool isZero() const {
212 for (int i = 0; i < SIZE; ++i) {
213 if (!math::isZero(mm[i])) return false;
214 }
215 return true;
216 }
217
218protected:
219 T mm[SIZE];
220};
221
222///////////////////////////////////////////////////////////////////////////
223
224template<int SIZE>
226{
227 return a & b;
228}
229
230template<int SIZE>
232{
233 return a | b;
234}
235
236///////////////////////////////////////////////////////////////////////////
237
238/// @return the absolute value of the given Tuple.
239template<int SIZE, typename T>
240Tuple<SIZE, T>
242{
243 Tuple<SIZE, T> result;
244 for (int i = 0; i < SIZE; ++i) result[i] = math::Abs(t[i]);
245 return result;
246}
247
248/// Return @c true if a Nan is present in the tuple.
249template<int SIZE, typename T>
250inline bool isNan(const Tuple<SIZE, T>& t) { return t.isNan(); }
251
252/// Return @c true if an Inf is present in the tuple.
253template<int SIZE, typename T>
254inline bool isInfinite(const Tuple<SIZE, T>& t) { return t.isInfinite(); }
255
256/// Return @c true if no Nan or Inf values are present.
257template<int SIZE, typename T>
258inline bool isFinite(const Tuple<SIZE, T>& t) { return t.isFinite(); }
259
260/// Return @c true if all elements are exactly equal to zero.
261template<int SIZE, typename T>
262inline bool isZero(const Tuple<SIZE, T>& t) { return t.isZero(); }
263
264////////////////////////////////////////
265
266
267/// Write a Tuple to an output stream
268template <int SIZE, typename T>
269std::ostream& operator<<(std::ostream& ostr, const Tuple<SIZE, T>& classname)
270{
271 ostr << classname.str();
272 return ostr;
273}
274
275} // namespace math
276} // namespace OPENVDB_VERSION_NAME
277} // namespace openvdb
278
279#endif // OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition Tuple.h:31
Tuple operator-(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:118
Tuple operator|(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:130
T operator[](IdxT i) const
Definition Tuple.h:70
Tuple & operator+=(Tuple in)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:134
bool isZero() const
True if all elements are exactly zero.
Definition Tuple.h:211
Tuple operator*(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:121
void write(std::ostream &os) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:179
Tuple< SIZE, bool > operator==(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:153
Tuple(const T val)
Constructor that fills this tuple with a value.
Definition Tuple.h:62
bool isInfinite() const
True if an Inf is present in this tuple.
Definition Tuple.h:195
Tuple operator+(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:115
T & operator[](IdxT i)
Definition Tuple.h:79
Tuple & operator/=(Tuple in)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:137
Tuple & operator-=(Tuple in)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:135
Tuple< SIZE, bool > operator!=(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:156
value_type const * asV() const
Exposes the internal array. Be careful when using this function.
Definition Tuple.h:108
Tuple< SIZE, bool > operator>(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:147
Tuple< SIZE, bool > operator>=(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:141
T mm[SIZE]
Copies this tuple into an array of a compatible type.
Definition Tuple.h:219
static const int size
Definition Tuple.h:36
Tuple operator/(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:124
Tuple & operator|=(Tuple in)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:139
Tuple & operator&=(Tuple in)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:138
value_type * asV()
Exposes the internal array. Be careful when using this function.
Definition Tuple.h:104
Tuple & operator*=(Tuple in)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:136
T operator[](int i) const
Definition Tuple.h:88
Tuple(Tuple< src_size, src_valtype > const &src)
Conversion constructor.
Definition Tuple.h:50
void toV(S *v) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:97
T & operator[](int i)
Definition Tuple.h:89
Tuple operator&(Tuple in) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:127
std::string str() const
Definition Tuple.h:163
T ValueType
Definition Tuple.h:34
bool isNan() const
True if a Nan is present in this tuple.
Definition Tuple.h:187
T value_type
Definition Tuple.h:33
void read(std::istream &is)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:182
bool isFinite() const
True if no Nan or Inf values are present.
Definition Tuple.h:203
Tuple< SIZE, bool > operator&&(const Tuple< SIZE, bool > a, const Tuple< SIZE, bool > b)
Definition Tuple.h:225
bool isInfinite(const float x)
Return true if x is an infinity value (either positive infinity or negative infinity).
Definition Math.h:399
std::ostream & operator<<(std::ostream &os, const BBox< Vec3T > &b)
Definition BBox.h:413
bool isFinite(const float x)
Return true if x is finite.
Definition Math.h:385
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:950
Tuple< SIZE, bool > operator||(const Tuple< SIZE, bool > a, const Tuple< SIZE, bool > b)
Definition Tuple.h:231
bool isNan(const float x)
Return true if x is a NaN (Not-A-Number) value.
Definition Math.h:413
bool operator<(const Vec2< T1 > &a, const Vec2< T2 > &b)=delete
Coord Abs(const Coord &xyz)
Definition Coord.h:518
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition Math.h:350
Definition Exceptions.h:13
Dummy class for tag dispatch of conversion constructors.
Definition Tuple.h:24
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284