QVM: Quaternions, Vectors, Matrices

quat_traits

#include <boost/qvm/quat_traits.hpp>

namespace
boost
{
    namespace
    qvm
    {
        template <class Q>
        struct quat_traits
        {
            /*main template members unspecified*/
        };
        
        /*
        User-defined (possibly partial) specializations:
        
        template <>
        struct quat_traits<Q>
        {
            typedef /*user-defined*/ scalar_type;        
        
            template <int I> static inline scalar_type read_element( Quaternion const & q );        
            template <int I> static inline scalar_type & write_element( Quaternion & q );        
        };
        */
    }
}

The quat_traits template must be specialized for (user-defined) quaternion types in order to enable quaternion operations defined in Boost QVM headers for objects of those types.

Note: quaternion types are not required to be copyable.

The main quat_traits template members are not specified. Valid specializations are required to define the following members:

In addition, valid specializations of the quat_traits template must define at least one of the following access functions as static members, where q is an object of type Quaternion, and I is compile-time integer constant:

  • read_element: the expression quat_traits<Quaternion>::read_element<I>(q) returns either a copy of or a const reference to the I-th element of q.
  • write_element: the expression quat_traits<Quaternion>::write_element<I>(q) returns mutable reference to the I-th element of q.

Note: For the quaternion a + bi + cj + dk, the elements are assumed to be in the following order: a, b, c, d; that is, I=0/1/2/3 would access a/b/c/d.

It is illegal to call any of the above functions unless is_quat<Quaternion>::value' is true. Even then, quaternion types are allowed to define only a subset of the access functions.

Below is an example of a user-defined quaternion type, and its corresponding specialization of the quat_traits template:

#include <boost/qvm/quat_traits.hpp>

struct fquat { float a[4]; };

namespace boost
{
    namespace qvm
    {
        template <>
        struct
        quat_traits<fquat>
        {
            typedef float scalar_type;

            template <int I> static inline scalar_type & write_element( fquat & q ) { return q.a[I]; }
            template <int I> static inline scalar_type read_element( fquat const & q ) { return q.a[I]; }
        };
    }
}

Equivalently, using the quat_traits_defaults template the above can be shortened to:

namespace boost
{
    namespace qvm
    {
        template <>
        struct
        quat_traits<fquat>: quat_traits_defaults<fquat,float>
        {
            template <int I> static inline scalar_type & write_element( fquat & q ) { return q.a[I]; }
        };
    }
}