OpenVDB 9.0.0
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
17namespace openvdb {
19namespace OPENVDB_VERSION_NAME {
20namespace math {
21
22/// @brief Dummy class for tag dispatch of conversion constructors
23struct Conversion {};
24
25
26/// @class Tuple "Tuple.h"
27/// A base class for homogenous tuple types
28template<int SIZE, typename T>
29class Tuple
30{
31public:
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
178protected:
179 T mm[SIZE];
180};
181
182
183////////////////////////////////////////
184
185
186/// @return true if t0 < t1, comparing components in order of significance.
187template<int SIZE, typename T0, typename T1>
188bool
189operator<(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.
199template<int SIZE, typename T0, typename T1>
200bool
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.
214template<int SIZE, typename T>
215Tuple<SIZE, 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.
224template<int SIZE, typename T>
225inline bool isNan(const Tuple<SIZE, T>& t) { return t.isNan(); }
226
227/// Return @c true if an Inf is present in the tuple.
228template<int SIZE, typename T>
229inline bool isInfinite(const Tuple<SIZE, T>& t) { return t.isInfinite(); }
230
231/// Return @c true if no Nan or Inf values are present.
232template<int SIZE, typename T>
233inline bool isFinite(const Tuple<SIZE, T>& t) { return t.isFinite(); }
234
235/// Return @c true if all elements are exactly equal to zero.
236template<int SIZE, typename T>
237inline bool isZero(const Tuple<SIZE, T>& t) { return t.isZero(); }
238
239////////////////////////////////////////
240
241
242/// Write a Tuple to an output stream
243template <int SIZE, typename T>
244std::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
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition: Tuple.h:30
bool isZero() const
True if all elements are exactly zero.
Definition: Tuple.h:171
void write(std::ostream &os) const
Copies this tuple into an array of a compatible type.
Definition: Tuple.h:139
bool isInfinite() const
True if an Inf is present in this tuple.
Definition: Tuple.h:155
value_type const * asV() const
Exposes the internal array. Be careful when using this function.
Definition: Tuple.h:117
T mm[SIZE]
Copies this tuple into an array of a compatible type.
Definition: Tuple.h:179
value_type * asV()
Exposes the internal array. Be careful when using this function.
Definition: Tuple.h:113
T operator[](int i) const
Definition: Tuple.h:86
Tuple(Tuple< src_size, src_valtype > const &src)
Conversion constructor.
Definition: Tuple.h:75
void toV(S *v) const
Copies this tuple into an array of a compatible type.
Definition: Tuple.h:106
T & operator[](int i)
Definition: Tuple.h:94
std::string str() const
Definition: Tuple.h:123
T ValueType
Definition: Tuple.h:33
bool isNan() const
True if a Nan is present in this tuple.
Definition: Tuple.h:147
T value_type
Definition: Tuple.h:32
void read(std::istream &is)
Copies this tuple into an array of a compatible type.
Definition: Tuple.h:142
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 isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:444
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 isFinite(const Tuple< SIZE, T > &t)
Return true if no Nan or Inf values are present.
Definition: Tuple.h:233
std::ostream & operator<<(std::ostream &ostr, const Tuple< SIZE, T > &classname)
Write a Tuple to an output stream.
Definition: Tuple.h:244
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition: Tuple.h:189
bool isNan(const Tuple< SIZE, T > &t)
Return true if a Nan is present in the tuple.
Definition: Tuple.h:225
Tuple< SIZE, T > Abs(const Tuple< SIZE, T > &t)
Definition: Tuple.h:216
Definition: Exceptions.h:13
Dummy class for tag dispatch of conversion constructors.
Definition: Tuple.h:23
#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