Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interoperability constructors #91

Merged
merged 7 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions config/ImathConfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@
(uint32_t(IMATH_VERSION_MINOR) << 16) | \
(uint32_t(IMATH_VERSION_PATCH) << 8))


//
// By default, opt into the interoparability constructors and assignments.
// If this causes problems, it can be disabled by defining this symbol to
// be 0 prior to including any Imath headers.
//
// If no such definition is found, we enable automatically unless we are
// using gcc 4.x, which appears to have bugs that prevent the interop
// templates from compiling correctly.
//
#ifndef IMATH_FOREIGN_VECTOR_INTEROP
# if defined(__GNUC__) && __GNUC__ == 4 && !defined(__clang__)
# define IMATH_FOREIGN_VECTOR_INTEROP 0
# else
# define IMATH_FOREIGN_VECTOR_INTEROP 1
# endif
#endif


//
// Decorator that makes a function available for both CPU and GPU, when
// compiling for Cuda.
Expand Down
1 change: 1 addition & 0 deletions src/Imath/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ imath_define_library(Imath
ImathRoots.h
ImathShear.h
ImathSphere.h
ImathTypeTraits.h
ImathVecAlgo.h
ImathVec.h
half.h
Expand Down
156 changes: 103 additions & 53 deletions src/Imath/ImathMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,35 @@ template <class T> class Matrix22

/// @}

#if IMATH_FOREIGN_VECTOR_INTEROP
/// @{
/// @name Interoperability with other matrix types
///
/// Construction and assignment are allowed from other classes that
/// appear to be equivalent matrix types, provided that they support
/// double-subscript (i.e., `m[j][i]`) giving the same type as the
/// elements of this matrix, and their total size appears to be the
/// right number of matrix elements.
///
/// This functionality is disabled for gcc 4.x, which seems to have a
/// compiler bug that results in spurious errors. It can also be
/// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
/// including any Imath header files.
///
template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,2,2>::value)>
IMATH_HOSTDEVICE explicit Matrix22 (const M& m)
: Matrix22(T(m[0][0]), T(m[0][1]), T(m[1][0]), T(m[1][1]))
{ }

template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,2,2>::value)>
IMATH_HOSTDEVICE const Matrix22& operator= (const M& m)
{
*this = Matrix22(T(m[0][0]), T(m[0][1]), T(m[1][0]), T(m[1][1]));
return *this;
}
/// @}
#endif

/// @{
/// @name Compatibility with Sb

Expand Down Expand Up @@ -278,23 +307,6 @@ template <class T> class Matrix22

/// The base vector type
typedef Vec2<T> BaseVecType;

private:
template <typename R, typename S> struct isSameType
{
enum
{
value = 0
};
};

template <typename R> struct isSameType<R, R>
{
enum
{
value = 1
};
};
};

///
Expand Down Expand Up @@ -365,7 +377,42 @@ template <class T> class Matrix33
~Matrix33() noexcept = default;

/// @}


#if IMATH_FOREIGN_VECTOR_INTEROP
/// @{
/// @name Interoperability with other matrix types
///
/// Construction and assignment are allowed from other classes that
/// appear to be equivalent matrix types, provided that they support
/// double-subscript (i.e., `m[j][i]`) giving the same type as the
/// elements of this matrix, and their total size appears to be the
/// right number of matrix elements.
///
/// This functionality is disabled for gcc 4.x, which seems to have a
/// compiler bug that results in spurious errors. It can also be
/// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
/// including any Imath header files.
///
template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,3,3>::value)>
IMATH_HOSTDEVICE explicit Matrix33 (const M& m)
: Matrix33(T(m[0][0]), T(m[0][1]), T(m[0][2]),
T(m[1][0]), T(m[1][1]), T(m[1][2]),
T(m[2][0]), T(m[2][1]), T(m[2][2]))
{ }

/// Interoperability assignment from another type that behaves as if it
/// were an equivalent matrix.
template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,3,3>::value)>
IMATH_HOSTDEVICE const Matrix33& operator= (const M& m)
{
*this = Matrix33(T(m[0][0]), T(m[0][1]), T(m[0][2]),
T(m[1][0]), T(m[1][1]), T(m[1][2]),
T(m[2][0]), T(m[2][1]), T(m[2][2]));
return *this;
}
/// @}
#endif

/// @{
/// @name Compatibility with Sb

Expand Down Expand Up @@ -604,23 +651,6 @@ template <class T> class Matrix33

/// The base vector type
typedef Vec3<T> BaseVecType;

private:
template <typename R, typename S> struct isSameType
{
enum
{
value = 0
};
};

template <typename R> struct isSameType<R, R>
{
enum
{
value = 1
};
};
};

///
Expand Down Expand Up @@ -704,7 +734,44 @@ template <class T> class Matrix44
~Matrix44() noexcept = default;

/// @}


#if IMATH_FOREIGN_VECTOR_INTEROP
/// @{
/// @name Interoperability with other matrix types
///
/// Construction and assignment are allowed from other classes that
/// appear to be equivalent matrix types, provided that they support
/// double-subscript (i.e., `m[j][i]`) giving the same type as the
/// elements of this matrix, and their total size appears to be the
/// right number of matrix elements.
///
/// This functionality is disabled for gcc 4.x, which seems to have a
/// compiler bug that results in spurious errors. It can also be
/// disabled by defining IMATH_FOREIGN_VECTOR_INTEROP to be 0 prior to
/// including any Imath header files.
///
template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,4,4>::value)>
IMATH_HOSTDEVICE explicit Matrix44 (const M& m)
: Matrix44(T(m[0][0]), T(m[0][1]), T(m[0][2]), T(m[0][3]),
T(m[1][0]), T(m[1][1]), T(m[1][2]), T(m[1][3]),
T(m[2][0]), T(m[2][1]), T(m[2][2]), T(m[2][3]),
T(m[3][0]), T(m[3][1]), T(m[3][2]), T(m[3][3]))
{ }

/// Interoperability assignment from another type that behaves as if it
/// were an equivalent matrix.
template<typename M, IMATH_ENABLE_IF(has_double_subscript<M,T,4,4>::value)>
IMATH_HOSTDEVICE const Matrix44& operator= (const M& m)
{
*this = Matrix44(T(m[0][0]), T(m[0][1]), T(m[0][2]), T(m[0][3]),
T(m[1][0]), T(m[1][1]), T(m[1][2]), T(m[1][3]),
T(m[2][0]), T(m[2][1]), T(m[2][2]), T(m[2][3]),
T(m[3][0]), T(m[3][1]), T(m[3][2]), T(m[3][3]));
return *this;
}
/// @}
#endif

/// @{
/// @name Compatibility with Sb

Expand Down Expand Up @@ -979,23 +1046,6 @@ template <class T> class Matrix44

/// The base vector type
typedef Vec4<T> BaseVecType;

private:
template <typename R, typename S> struct isSameType
{
enum
{
value = 0
};
};

template <typename R> struct isSameType<R, R>
{
enum
{
value = 1
};
};
};

/// Stream output
Expand Down
20 changes: 0 additions & 20 deletions src/Imath/ImathPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,6 @@ IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
#endif


//
// Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
//
#if (IMATH_CPLUSPLUS_VERSION >= 14)
using std::enable_if_t; // Use C++14 std::enable_if_t
#else
// Define enable_if_t for C++11
template <bool B, class T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
#endif


//
// An enable_if helper to be used in template parameters which results in
// much shorter symbols.
//
#define IMATH_ENABLE_IF(...) Imath::enable_if_t<(__VA_ARGS__), int> = 0



#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
Expand Down
Loading