OpenVDB 12.0.0
 
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 const access to an element in the tuple. The offset idx must be
62 // an integral type. A copy of the tuple data is returned.
63 template <typename IdxT,
64 typename std::enable_if<std::is_integral<IdxT>::value, bool>::type = true>
65 T operator[](IdxT i) const {
66 OPENVDB_ASSERT(i >= IdxT(0) && i < IdxT(SIZE));
67 return mm[i];
68 }
69
70 // @brief non-const access to an element in the tuple. The offset idx must be
71 // an integral type. A reference to the tuple data is returned.
72 template <typename IdxT,
73 typename std::enable_if<std::is_integral<IdxT>::value, bool>::type = true>
74 T& operator[](IdxT i) {
75 OPENVDB_ASSERT(i >= IdxT(0) && i < IdxT(SIZE));
76 return mm[i];
77 }
78
79 // These exist solely to provide backwards compatibility with [] access of
80 // non-integer types that were castable to 'int' (such as floating point type).
81 // The above templates allow for any integer type to be used as an offset into
82 // the tuple data.
83 T operator[](int i) const { return this->template operator[]<int>(i); }
84 T& operator[](int i) { return this->template operator[]<int>(i); }
85
86 /// @name Compatibility
87 /// These are mostly for backwards compatibility with functions that take
88 /// old-style Vs (which are just arrays).
89 //@{
90 /// Copies this tuple into an array of a compatible type
91 template <typename S>
92 void toV(S *v) const {
93 for (int i = 0; i < SIZE; ++i) {
94 v[i] = mm[i];
95 }
96 }
97
98 /// Exposes the internal array. Be careful when using this function.
100 return mm;
101 }
102 /// Exposes the internal array. Be careful when using this function.
103 value_type const *asV() const {
104 return mm;
105 }
106 //@} Compatibility
107
108 /// @return string representation of Classname
109 std::string str() const {
110 std::ostringstream buffer;
111
112 buffer << "[";
113
114 // For each column
115 for (unsigned j(0); j < SIZE; j++) {
116 if (j) buffer << ", ";
117 buffer << PrintCast(mm[j]);
118 }
119
120 buffer << "]";
121
122 return buffer.str();
123 }
124
125 void write(std::ostream& os) const {
126 os.write(reinterpret_cast<const char*>(&mm), sizeof(T)*SIZE);
127 }
128 void read(std::istream& is) {
129 is.read(reinterpret_cast<char*>(&mm), sizeof(T)*SIZE);
130 }
131
132 /// True if a Nan is present in this tuple
133 bool isNan() const {
134 for (int i = 0; i < SIZE; ++i) {
135 if (math::isNan(mm[i])) return true;
136 }
137 return false;
138 }
139
140 /// True if an Inf is present in this tuple
141 bool isInfinite() const {
142 for (int i = 0; i < SIZE; ++i) {
143 if (math::isInfinite(mm[i])) return true;
144 }
145 return false;
146 }
147
148 /// True if no Nan or Inf values are present
149 bool isFinite() const {
150 for (int i = 0; i < SIZE; ++i) {
151 if (!math::isFinite(mm[i])) return false;
152 }
153 return true;
154 }
155
156 /// True if all elements are exactly zero
157 bool isZero() const {
158 for (int i = 0; i < SIZE; ++i) {
159 if (!math::isZero(mm[i])) return false;
160 }
161 return true;
162 }
163
164protected:
165 T mm[SIZE];
166};
167
168
169////////////////////////////////////////
170
171
172/// @return true if t0 < t1, comparing components in order of significance.
173template<int SIZE, typename T0, typename T1>
174bool
175operator<(const Tuple<SIZE, T0>& t0, const Tuple<SIZE, T1>& t1)
176{
177 for (int i = 0; i < SIZE-1; ++i) {
178 if (!isExactlyEqual(t0[i], t1[i])) return t0[i] < t1[i];
179 }
180 return t0[SIZE-1] < t1[SIZE-1];
181}
182
183
184/// @return true if t0 > t1, comparing components in order of significance.
185template<int SIZE, typename T0, typename T1>
186bool
188{
189 for (int i = 0; i < SIZE-1; ++i) {
190 if (!isExactlyEqual(t0[i], t1[i])) return t0[i] > t1[i];
191 }
192 return t0[SIZE-1] > t1[SIZE-1];
193}
194
195
196////////////////////////////////////////
197
198
199/// @return the absolute value of the given Tuple.
200template<int SIZE, typename T>
201Tuple<SIZE, T>
203{
204 Tuple<SIZE, T> result;
205 for (int i = 0; i < SIZE; ++i) result[i] = math::Abs(t[i]);
206 return result;
207}
208
209/// Return @c true if a Nan is present in the tuple.
210template<int SIZE, typename T>
211inline bool isNan(const Tuple<SIZE, T>& t) { return t.isNan(); }
212
213/// Return @c true if an Inf is present in the tuple.
214template<int SIZE, typename T>
215inline bool isInfinite(const Tuple<SIZE, T>& t) { return t.isInfinite(); }
216
217/// Return @c true if no Nan or Inf values are present.
218template<int SIZE, typename T>
219inline bool isFinite(const Tuple<SIZE, T>& t) { return t.isFinite(); }
220
221/// Return @c true if all elements are exactly equal to zero.
222template<int SIZE, typename T>
223inline bool isZero(const Tuple<SIZE, T>& t) { return t.isZero(); }
224
225////////////////////////////////////////
226
227
228/// Write a Tuple to an output stream
229template <int SIZE, typename T>
230std::ostream& operator<<(std::ostream& ostr, const Tuple<SIZE, T>& classname)
231{
232 ostr << classname.str();
233 return ostr;
234}
235
236} // namespace math
237} // namespace OPENVDB_VERSION_NAME
238} // namespace openvdb
239
240#endif // OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
OPENVDB_API std::ostream & operator<<(std::ostream &os, half h)
Output h to os, formatted as a float.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition Tuple.h:31
T operator[](IdxT i) const
Definition Tuple.h:65
bool isZero() const
True if all elements are exactly zero.
Definition Tuple.h:157
void write(std::ostream &os) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:125
bool isInfinite() const
True if an Inf is present in this tuple.
Definition Tuple.h:141
T & operator[](IdxT i)
Definition Tuple.h:74
value_type const * asV() const
Exposes the internal array. Be careful when using this function.
Definition Tuple.h:103
T mm[SIZE]
Copies this tuple into an array of a compatible type.
Definition Tuple.h:165
static const int size
Definition Tuple.h:36
value_type * asV()
Exposes the internal array. Be careful when using this function.
Definition Tuple.h:99
T operator[](int i) const
Definition Tuple.h:83
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:92
T & operator[](int i)
Definition Tuple.h:84
std::string str() const
Definition Tuple.h:109
T ValueType
Definition Tuple.h:34
bool isNan() const
True if a Nan is present in this tuple.
Definition Tuple.h:133
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:128
bool isFinite() const
True if no Nan or Inf values are present.
Definition Tuple.h:149
bool isInfinite(const float x)
Return true if x is an infinity value (either positive infinity or negative infinity).
Definition Math.h:385
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition Tuple.h:175
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition Tuple.h:187
bool isFinite(const float x)
Return true if x is finite.
Definition Math.h:375
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:882
bool isNan(const float x)
Return true if x is a NaN (Not-A-Number) value.
Definition Math.h:395
Coord Abs(const Coord &xyz)
Definition Coord.h:518
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition Math.h:443
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition Math.h:337
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:218