Loading...
Searching...
No Matches
Tuple.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
//
/// @file Tuple.h
/// @author Ben Kwa
#ifndef OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
#define OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
#include "Math.h"
#include <cmath>
#include <sstream>
#include <string>
#include <type_traits>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace math {
/// @brief Dummy class for tag dispatch of conversion constructors
struct Conversion {};
/// @class Tuple "Tuple.h"
/// A base class for homogenous tuple types
template<int SIZE, typename T>
class Tuple
{
public:
using value_type = T;
using ValueType = T;
static const int size = SIZE;
/// Trivial constructor, the Tuple is NOT initialized
/// @note destructor, copy constructor, assignment operator and
/// move constructor are left to be defined by the compiler (default)
Tuple() = default;
/// @brief Conversion constructor.
/// @details Tuples with different value types and different sizes can be
/// interconverted using this member. Converting from a larger tuple
/// results in truncation; converting from a smaller tuple results in
/// the extra data members being zeroed out. This function assumes that
/// the integer 0 is convertible to the tuple's value type.
template <int src_size, typename src_valtype>
explicit Tuple(Tuple<src_size, src_valtype> const &src) {
enum { COPY_END = (SIZE < src_size ? SIZE : src_size) };
for (int i = 0; i < COPY_END; ++i) {
mm[i] = src[i];
}
for (int i = COPY_END; i < SIZE; ++i) {
mm[i] = 0;
}
}
// @brief const access to an element in the tuple. The offset idx must be
// an integral type. A copy of the tuple data is returned.
template <typename IdxT,
typename std::enable_if<std::is_integral<IdxT>::value, bool>::type = true>
T operator[](IdxT i) const {
assert(i >= IdxT(0) && i < IdxT(SIZE));
return mm[i];
}
// @brief non-const access to an element in the tuple. The offset idx must be
// an integral type. A reference to the tuple data is returned.
template <typename IdxT,
typename std::enable_if<std::is_integral<IdxT>::value, bool>::type = true>
T& operator[](IdxT i) {
assert(i >= IdxT(0) && i < IdxT(SIZE));
return mm[i];
}
// These exist solely to provide backwards compatibility with [] access of
// non-integer types that were castable to 'int' (such as floating point type).
// The above templates allow for any integer type to be used as an offset into
// the tuple data.
T operator[](int i) const { return this->template operator[]<int>(i); }
T& operator[](int i) { return this->template operator[]<int>(i); }
/// @name Compatibility
/// These are mostly for backwards compatibility with functions that take
/// old-style Vs (which are just arrays).
//@{
/// Copies this tuple into an array of a compatible type
template <typename S>
void toV(S *v) const {
for (int i = 0; i < SIZE; ++i) {
v[i] = mm[i];
}
}
/// Exposes the internal array. Be careful when using this function.
value_type *asV() {
return mm;
}
/// Exposes the internal array. Be careful when using this function.
value_type const *asV() const {
return mm;
}
//@} Compatibility
/// @return string representation of Classname
std::string str() const {
std::ostringstream buffer;
buffer << "[";
// For each column
for (unsigned j(0); j < SIZE; j++) {
if (j) buffer << ", ";
buffer << PrintCast(mm[j]);
}
buffer << "]";
return buffer.str();
}
void write(std::ostream& os) const {
os.write(reinterpret_cast<const char*>(&mm), sizeof(T)*SIZE);
}
void read(std::istream& is) {
is.read(reinterpret_cast<char*>(&mm), sizeof(T)*SIZE);
}
/// True if a Nan is present in this tuple
bool isNan() const {
for (int i = 0; i < SIZE; ++i) {
if (math::isNan(mm[i])) return true;
}
return false;
}
/// True if an Inf is present in this tuple
bool isInfinite() const {
for (int i = 0; i < SIZE; ++i) {
if (math::isInfinite(mm[i])) return true;
}
return false;
}
/// True if no Nan or Inf values are present
bool isFinite() const {
for (int i = 0; i < SIZE; ++i) {
if (!math::isFinite(mm[i])) return false;
}
return true;
}
/// True if all elements are exactly zero
bool isZero() const {
for (int i = 0; i < SIZE; ++i) {
if (!math::isZero(mm[i])) return false;
}
return true;
}
protected:
T mm[SIZE];
};
////////////////////////////////////////
/// @return true if t0 < t1, comparing components in order of significance.
template<int SIZE, typename T0, typename T1>
bool
operator<(const Tuple<SIZE, T0>& t0, const Tuple<SIZE, T1>& t1)
{
for (int i = 0; i < SIZE-1; ++i) {
if (!isExactlyEqual(t0[i], t1[i])) return t0[i] < t1[i];
}
return t0[SIZE-1] < t1[SIZE-1];
}
/// @return true if t0 > t1, comparing components in order of significance.
template<int SIZE, typename T0, typename T1>
bool
operator>(const Tuple<SIZE, T0>& t0, const Tuple<SIZE, T1>& t1)
{
for (int i = 0; i < SIZE-1; ++i) {
if (!isExactlyEqual(t0[i], t1[i])) return t0[i] > t1[i];
}
return t0[SIZE-1] > t1[SIZE-1];
}
////////////////////////////////////////
/// @return the absolute value of the given Tuple.
template<int SIZE, typename T>
Tuple<SIZE, T>
Abs(const Tuple<SIZE, T>& t)
{
Tuple<SIZE, T> result;
for (int i = 0; i < SIZE; ++i) result[i] = math::Abs(t[i]);
return result;
}
/// Return @c true if a Nan is present in the tuple.
template<int SIZE, typename T>
inline bool isNan(const Tuple<SIZE, T>& t) { return t.isNan(); }
/// Return @c true if an Inf is present in the tuple.
template<int SIZE, typename T>
inline bool isInfinite(const Tuple<SIZE, T>& t) { return t.isInfinite(); }
/// Return @c true if no Nan or Inf values are present.
template<int SIZE, typename T>
inline bool isFinite(const Tuple<SIZE, T>& t) { return t.isFinite(); }
/// Return @c true if all elements are exactly equal to zero.
template<int SIZE, typename T>
inline bool isZero(const Tuple<SIZE, T>& t) { return t.isZero(); }
////////////////////////////////////////
/// Write a Tuple to an output stream
template <int SIZE, typename T>
std::ostream& operator<<(std::ostream& ostr, const Tuple<SIZE, T>& classname)
{
ostr << classname.str();
return ostr;
}
} // namespace math
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_MATH_TUPLE_HAS_BEEN_INCLUDED
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v11_0::math::Tuple
Definition Tuple.h:30
openvdb::v11_0::math::Tuple::operator[]
T operator[](IdxT i) const
Definition Tuple.h:64
openvdb::v11_0::math::Tuple::isZero
bool isZero() const
True if all elements are exactly zero.
Definition Tuple.h:156
openvdb::v11_0::math::Tuple::write
void write(std::ostream &os) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:124
openvdb::v11_0::math::Tuple::isInfinite
bool isInfinite() const
True if an Inf is present in this tuple.
Definition Tuple.h:140
openvdb::v11_0::math::Tuple::operator[]
T & operator[](IdxT i)
Definition Tuple.h:73
openvdb::v11_0::math::Tuple::asV
value_type const * asV() const
Exposes the internal array. Be careful when using this function.
Definition Tuple.h:102
openvdb::v11_0::math::Tuple::asV
value_type * asV()
Exposes the internal array. Be careful when using this function.
Definition Tuple.h:98
openvdb::v11_0::math::Tuple::operator[]
T operator[](int i) const
Definition Tuple.h:82
openvdb::v11_0::math::Tuple::Tuple
Tuple(Tuple< src_size, src_valtype > const &src)
Conversion constructor.
Definition Tuple.h:49
openvdb::v11_0::math::Tuple::toV
void toV(S *v) const
Copies this tuple into an array of a compatible type.
Definition Tuple.h:91
openvdb::v11_0::math::Tuple::operator[]
T & operator[](int i)
Definition Tuple.h:83
openvdb::v11_0::math::Tuple::Tuple
Tuple()=default
openvdb::v11_0::math::Tuple::str
std::string str() const
Definition Tuple.h:108
openvdb::v11_0::math::Tuple::ValueType
T ValueType
Definition Tuple.h:33
openvdb::v11_0::math::Tuple::isNan
bool isNan() const
True if a Nan is present in this tuple.
Definition Tuple.h:132
openvdb::v11_0::math::Tuple::value_type
T value_type
Definition Tuple.h:32
openvdb::v11_0::math::Tuple::read
void read(std::istream &is)
Copies this tuple into an array of a compatible type.
Definition Tuple.h:127
openvdb::v11_0::math::Tuple::isFinite
bool isFinite() const
True if no Nan or Inf values are present.
Definition Tuple.h:148
openvdb::v11_0::math::isInfinite
bool isInfinite(const float x)
Return true if x is an infinity value (either positive infinity or negative infinity).
Definition Math.h:385
openvdb::v11_0::math::operator<
bool operator<(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition Tuple.h:174
openvdb::v11_0::math::operator>
bool operator>(const Tuple< SIZE, T0 > &t0, const Tuple< SIZE, T1 > &t1)
Definition Tuple.h:186
openvdb::v11_0::math::isFinite
bool isFinite(const float x)
Return true if x is finite.
Definition Math.h:375
openvdb::v11_0::math::PrintCast
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
openvdb::v11_0::math::isNan
bool isNan(const float x)
Return true if x is a NaN (Not-A-Number) value.
Definition Math.h:395
openvdb::v11_0::math::Abs
Coord Abs(const Coord &xyz)
Definition Coord.h:517
openvdb::v11_0::math::isExactlyEqual
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition Math.h:443
openvdb::v11_0::math::isZero
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition Math.h:337
openvdb::v11_0::operator<<
std::ostream & operator<<(std::ostream &ostr, const Metadata &metadata)
Write a Metadata to an output stream.
Definition Metadata.h:351
openvdb
Definition Exceptions.h:13
openvdb::v11_0::math::Conversion
Dummy class for tag dispatch of conversion constructors.
Definition Tuple.h:23
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212