# 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:

- scalar_type: the expression quat_traits<Quaternion>::scalar_type must be a value type which satisfies the scalar requirements.

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]; }
            };
        }
    }

See also: boost/qvm/quat_traits.hpp | boost/qvm/quat_traits_array.hpp | is_quat | mag(quat) | mag_sqr(quat) | normalize(quat) | quat | quat_traits<Q>::read_element | quat_traits<Q>::scalar_type | quat_traits<Q>::write_element | quat_traits_defaults | rotate(quat,vec,scalar) | rotate_x(quat,scalar) | rotate_y(quat,scalar) | rotate_z(quat,scalar) | scalar | set_identity(quat) | set_rotx(quat,scalar) | set_roty(quat,scalar) | set_rotz(quat,scalar) | set_zero(quat) | View Proxy