• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
6<meta name="viewport" content="width=device-width, initial-scale=1.0">
7<meta name="generator" content="Asciidoctor 1.5.8">
8<meta name="author" content="Quaternion / Vector / Matrix Library for C&#43;&#43;-11 | Emil Dotchevski">
9<title>QVM</title>
10<link rel="stylesheet" href="./zajo-dark.css">
11<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
12<meta name="keywords" content="c++,quaternion,vector,matrix,open source">
13<meta name="description" content="Generic C++ library for working with Quaternions, Vectors and Matrices">
14<link rel="stylesheet" href="./zajo-light.css" disabled=true>
15<script>
16function switch_style()
17{
18	var i, tag;
19	for( i=0, tag=document.getElementsByTagName("link"); i<tag.length; i++ )
20		if( tag[i].rel.indexOf("stylesheet")!=-1 && tag[i].href.includes("zajo-") )
21			tag[i].disabled = !tag[i].disabled;
22}
23</script>
24</head>
25<body class="article toc2 toc-left">
26<div id="header">
27<h1>QVM <a href="https://ci.appveyor.com/project/zajo/qvm"><img style="margin-left:8px; margin-top:21px; float:right; vertical-align: top" src="https://ci.appveyor.com/api/projects/status/rphx1liilphuk1t5?svg=true"></a> <a href="https://travis-ci.org/boostorg/qvm"><img style="margin-top:21px; float:right; vertical-align: top" src="https://travis-ci.org/boostorg/qvm.svg?branch=master"></a><div style="z-index: 3; bottom:-16px; right:4px; position:fixed"><input width="32" height="32" type="image" alt="Skin" src="./skin.png" onclick="this.blur();switch_style();return false;"/></div></h1>
28<div class="details">
29<span id="author" class="author">Quaternion / Vector / Matrix Library for C&#43;&#43;-11 | Emil Dotchevski</span><br>
30</div>
31<div id="toc" class="toc2">
32<div id="toctitle"></div>
33<ul class="sectlevel1">
34<li><a href="#_abstract">Abstract</a></li>
35<li><a href="#tutorial">Tutorial</a>
36<ul class="sectlevel2">
37<li><a href="#_quaternions_vectors_matrices">Quaternions, Vectors, Matrices</a></li>
38<li><a href="#_c_arrays">C Arrays</a></li>
39<li><a href="#view_proxy">View proxies</a></li>
40<li><a href="#_swizzling">Swizzling</a></li>
41<li><a href="#enable_if">SFINAE/enable_if</a></li>
42<li><a href="#_interoperability">Interoperability</a>
43<ul class="sectlevel3">
44<li><a href="#_specifying_return_types_for_binary_operations">Specifying return types for binary operations</a></li>
45<li><a href="#_specifying_return_types_for_unary_operations">Specifying return types for unary operations</a></li>
46<li><a href="#_converting_between_different_quaternion_vector_and_matrix_types">Converting between different quaternion, vector and matrix types</a></li>
47</ul>
48</li>
49</ul>
50</li>
51<li><a href="#reference">Reference</a>
52<ul class="sectlevel2">
53<li><a href="#_header_files">Header Files</a></li>
54<li><a href="#type_traits">Type Traits System</a>
55<ul class="sectlevel3">
56<li><a href="#scalar_requirements">Scalar Requirements</a></li>
57<li><a href="#is_scalar"><code>is_scalar</code></a></li>
58<li><a href="#scalar_traits"><code>scalar_traits</code></a></li>
59<li><a href="#deduce_scalar"><code>deduce_scalar</code></a></li>
60<li><a href="#scalar"><code>scalar</code></a></li>
61<li><a href="#is_quat"><code>is_quat</code></a></li>
62<li><a href="#quat_traits"><code>quat_traits</code></a></li>
63<li><a href="#quat_traits_defaults"><code>quat_traits_defaults</code></a></li>
64<li><a href="#deduce_quat"><code>deduce_quat</code></a></li>
65<li><a href="#deduce_quat2"><code>deduce_quat2</code></a></li>
66<li><a href="#is_vec"><code>is_vec</code></a></li>
67<li><a href="#vec_traits"><code>vec_traits</code></a></li>
68<li><a href="#vec_traits_defaults"><code>vec_traits_defaults</code></a></li>
69<li><a href="#deduce_vec"><code>deduce_vec</code></a></li>
70<li><a href="#deduce_vec2"><code>deduce_vec2</code></a></li>
71<li><a href="#is_mat"><code>is_mat</code></a></li>
72<li><a href="#mat_traits"><code>mat_traits</code></a></li>
73<li><a href="#mat_traits_defaults"><code>mat_traits_defaults</code></a></li>
74<li><a href="#deduce_mat"><code>deduce_mat</code></a></li>
75<li><a href="#deduce_mat2"><code>deduce_mat2</code></a></li>
76</ul>
77</li>
78<li><a href="#_built_in_quaternion_vector_and_matrix_types">Built-in Quaternion, Vector and Matrix Types</a>
79<ul class="sectlevel3">
80<li><a href="#quat"><code>quat</code></a></li>
81<li><a href="#vec"><code>vec</code></a></li>
82<li><a href="#mat"><code>mat</code></a></li>
83</ul>
84</li>
85<li><a href="#_element_access">Element Access</a>
86<ul class="sectlevel3">
87<li><a href="#quat_access">Quaternions</a></li>
88<li><a href="#vec_access">Vectors</a></li>
89<li><a href="#swizzling">Vector Element Swizzling</a></li>
90<li><a href="#mat_access">Matrices</a></li>
91</ul>
92</li>
93<li><a href="#_quaternion_operations">Quaternion Operations</a>
94<ul class="sectlevel3">
95<li><a href="#quat_assign"><code>assign</code></a></li>
96<li><a href="#quat_convert_to"><code>convert_to</code></a></li>
97<li><a href="#quat_minus_eq"><code>operator-=</code></a></li>
98<li><a href="#quat_minus_unary"><code>operator-</code> (unary)</a></li>
99<li><a href="#quat_minus"><code>operator-</code> (binary)</a></li>
100<li><a href="#quat_plus_eq"><code>operator+=</code></a></li>
101<li><a href="#quat_plus"><code>operator+</code></a></li>
102<li><a href="#quat_div_eq_scalar"><code>operator/=</code> (scalar)</a></li>
103<li><a href="#quat_div_scalar"><code>operator/</code> (scalar)</a></li>
104<li><a href="#quat_mul_eq_scalar"><code>operator*=</code> (scalar)</a></li>
105<li><a href="#quat_mul_eq"><code>operator*=</code></a></li>
106<li><a href="#quat_mul_scalar"><code>operator*</code> (scalar)</a></li>
107<li><a href="#quat_mul"><code>operator*</code></a></li>
108<li><a href="#quat_eq"><code>operator==</code></a></li>
109<li><a href="#quat_neq"><code>operator!=</code></a></li>
110<li><a href="#quat_cmp"><code>cmp</code></a></li>
111<li><a href="#quat_mag_sqr"><code>mag_sqr</code></a></li>
112<li><a href="#quat_mag"><code>mag</code></a></li>
113<li><a href="#quat_normalized"><code>normalized</code></a></li>
114<li><a href="#quat_normalize"><code>normalize</code></a></li>
115<li><a href="#quat_dot"><code>dot</code></a></li>
116<li><a href="#conjugate"><code>conjugate</code></a></li>
117<li><a href="#quat_inverse"><code>inverse</code></a></li>
118<li><a href="#slerp"><code>slerp</code></a></li>
119<li><a href="#zero_quat"><code>zero_quat</code></a></li>
120<li><a href="#quat_set_zero"><code>set_zero</code></a></li>
121<li><a href="#identity_quat"><code>identity_quat</code></a></li>
122<li><a href="#quat_set_identity"><code>set_identity</code></a></li>
123<li><a href="#rot_quat"><code>rot_quat</code></a></li>
124<li><a href="#quat_set_rot"><code>set_rot</code></a></li>
125<li><a href="#quat_rotate"><code>rotate</code></a></li>
126<li><a href="#rotx_quat"><code>rotx_quat</code></a></li>
127<li><a href="#quat_set_rotx"><code>set_rotx</code></a></li>
128<li><a href="#quat_rotate_x"><code>rotate_x</code></a></li>
129<li><a href="#roty_quat"><code>roty_quat</code></a></li>
130<li><a href="#quat_set_roty"><code>set_roty</code></a></li>
131<li><a href="#quat_rotate_y"><code>rotate_y</code></a></li>
132<li><a href="#rotz_quat"><code>rotz_quat</code></a></li>
133<li><a href="#quat_set_rotz"><code>set_rotz</code></a></li>
134<li><a href="#quat_rotate_z"><code>rotate_z</code></a></li>
135<li><a href="#quat_scalar_cast"><code>scalar_cast</code></a></li>
136<li><a href="#qref"><code>qref</code></a></li>
137</ul>
138</li>
139<li><a href="#_vector_operations">Vector Operations</a>
140<ul class="sectlevel3">
141<li><a href="#vec_assign"><code>assign</code></a></li>
142<li><a href="#vec_convert_to"><code>convert_to</code></a></li>
143<li><a href="#vec_minus_eq"><code>operator-=</code></a></li>
144<li><a href="#vec_minus_unary"><code>operator-</code> (unary)</a></li>
145<li><a href="#vec_minus"><code>operator-</code> (binary)</a></li>
146<li><a href="#vec_plus_eq"><code>operator+=</code></a></li>
147<li><a href="#vec_plus"><code>operator+</code></a></li>
148<li><a href="#vec_div_eq_scalar"><code>operator/=</code> (scalar)</a></li>
149<li><a href="#vec_div_scalar"><code>operator/</code></a></li>
150<li><a href="#vec_mul_eq_scalar"><code>operator*=</code></a></li>
151<li><a href="#vec_mul_scalar"><code>operator*</code></a></li>
152<li><a href="#vec_eq"><code>operator==</code></a></li>
153<li><a href="#vec_neq"><code>operator!=</code></a></li>
154<li><a href="#vec_cmp"><code>cmp</code></a></li>
155<li><a href="#vec_mag_sqr"><code>mag_sqr</code></a></li>
156<li><a href="#vec_mag"><code>mag</code></a></li>
157<li><a href="#vec_normalized"><code>normalized</code></a></li>
158<li><a href="#vec_normalize"><code>normalize</code></a></li>
159<li><a href="#vec_dot"><code>dot</code></a></li>
160<li><a href="#vec_cross"><code>cross</code></a></li>
161<li><a href="#zero_vec"><code>zero_vec</code></a></li>
162<li><a href="#vec_set_zero"><code>set_zero</code></a></li>
163<li><a href="#vec_scalar_cast"><code>scalar_cast</code></a></li>
164<li><a href="#vref"><code>vref</code></a></li>
165</ul>
166</li>
167<li><a href="#_matrix_operations">Matrix Operations</a>
168<ul class="sectlevel3">
169<li><a href="#mat_assign"><code>assign</code></a></li>
170<li><a href="#mat_convert_to"><code>convert_to</code></a></li>
171<li><a href="#mat_minus_eq_scalar"><code>operator-=</code></a></li>
172<li><a href="#mat_minus_unary"><code>operator-</code> (unary)</a></li>
173<li><a href="#mat_minus"><code>operator-</code></a></li>
174<li><a href="#mat_plus_eq_scalar"><code>operator+=</code></a></li>
175<li><a href="#mat_plus"><code>operator+</code></a></li>
176<li><a href="#mat_div_eq_scalar"><code>operator/=</code> (scalar)</a></li>
177<li><a href="#mat_div_scalar"><code>operator/</code> (scalar)</a></li>
178<li><a href="#mat_mul_eq"><code>operator*=</code></a></li>
179<li><a href="#mat_mul_eq_scalar"><code>operator*=</code> (scalar)</a></li>
180<li><a href="#mat_mul"><code>operator*</code></a></li>
181<li><a href="#mat_mul_scalar"><code>operator*</code> (scalar)</a></li>
182<li><a href="#mat_eq"><code>operator==</code></a></li>
183<li><a href="#mat_neq"><code>operator!=</code></a></li>
184<li><a href="#mat_cmp"><code>cmp</code></a></li>
185<li><a href="#mat_inverse"><code>inverse</code></a></li>
186<li><a href="#zero_mat"><code>zero_mat</code></a></li>
187<li><a href="#mat_set_zero"><code>set_zero</code></a></li>
188<li><a href="#identity_mat"><code>identity_mat</code></a></li>
189<li><a href="#mat_set_identity"><code>set_identity</code></a></li>
190<li><a href="#rot_mat"><code>rot_mat</code> / Euler angles</a></li>
191<li><a href="#mat_set_rot"><code>set_rot</code> / Euler angles</a></li>
192<li><a href="#mat_rotate"><code>rotate</code> / Euler angles</a></li>
193<li><a href="#rotx_mat"><code>rotx_mat</code></a></li>
194<li><a href="#mat_set_rotx"><code>set_rotx</code></a></li>
195<li><a href="#mat_rotate_x"><code>rotate_x</code></a></li>
196<li><a href="#roty_mat"><code>roty_mat</code></a></li>
197<li><a href="#mat_set_roty"><code>set_roty</code></a></li>
198<li><a href="#mat_rotate_y"><code>rotate_y</code></a></li>
199<li><a href="#rotz_mat"><code>rotz_mat</code></a></li>
200<li><a href="#mat_set_rotz"><code>set_rotz</code></a></li>
201<li><a href="#mat_rotate_z"><code>rotate_z</code></a></li>
202<li><a href="#determinant"><code>determinant</code></a></li>
203<li><a href="#perspective_lh"><code>perspective_lh</code></a></li>
204<li><a href="#perspective_rh"><code>perspective_rh</code></a></li>
205<li><a href="#mat_scalar_cast"><code>scalar_cast</code></a></li>
206<li><a href="#mref"><code>mref</code></a></li>
207</ul>
208</li>
209<li><a href="#_quaternion_vector_operations">Quaternion-Vector Operations</a>
210<ul class="sectlevel3">
211<li><a href="#quat_vec_mul"><code>operator*</code></a></li>
212</ul>
213</li>
214<li><a href="#_matrix_vector_operations">Matrix-Vector Operations</a>
215<ul class="sectlevel3">
216<li><a href="#mat_vec_mul"><code>operator*</code></a></li>
217<li><a href="#transform_vector"><code>transform_vector</code></a></li>
218<li><a href="#transform_point"><code>transform_point</code></a></li>
219</ul>
220</li>
221<li><a href="#_matrix_to_matrix_view_proxies">Matrix-to-Matrix View Proxies</a>
222<ul class="sectlevel3">
223<li><a href="#del_row"><code>del_row</code></a></li>
224<li><a href="#del_col"><code>del_col</code></a></li>
225<li><a href="#del_row_col"><code>del_row_col</code></a></li>
226<li><a href="#neg_row"><code>neg_row</code></a></li>
227<li><a href="#neg_col"><code>neg_col</code></a></li>
228<li><a href="#swap_rows"><code>swap_rows</code></a></li>
229<li><a href="#swap_cols"><code>swap_cols</code></a></li>
230<li><a href="#transposed"><code>transposed</code></a></li>
231</ul>
232</li>
233<li><a href="#_vector_to_matrix_view_proxies">Vector-to-Matrix View Proxies</a>
234<ul class="sectlevel3">
235<li><a href="#col_mat"><code>col_mat</code></a></li>
236<li><a href="#row_mat"><code>row_mat</code></a></li>
237<li><a href="#translation_mat"><code>translation_mat</code></a></li>
238<li><a href="#diag_mat"><code>diag_mat</code></a></li>
239</ul>
240</li>
241<li><a href="#_matrix_to_vector_view_proxies">Matrix-to-Vector View Proxies</a>
242<ul class="sectlevel3">
243<li><a href="#col"><code>col</code></a></li>
244<li><a href="#row"><code>row</code></a></li>
245<li><a href="#diag"><code>diag</code></a></li>
246<li><a href="#translation"><code>translation</code></a></li>
247</ul>
248</li>
249<li><a href="#_exceptions">Exceptions</a>
250<ul class="sectlevel3">
251<li><a href="#error"><code>error</code></a></li>
252<li><a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a></li>
253<li><a href="#zero_determinant_error"><code>zero_determinant_error</code></a></li>
254</ul>
255</li>
256<li><a href="#_macros_and_configuration_boost_qvm">Macros and Configuration: BOOST_QVM_</a>
257<ul class="sectlevel3">
258<li><a href="#BOOST_QVM_INLINE"><code>INLINE</code></a></li>
259<li><a href="#BOOST_QVM_FORCE_INLINE"><code>FORCE_INLINE</code></a></li>
260<li><a href="#BOOST_QVM_INLINE_TRIVIAL"><code>INLINE_TRIVIAL</code></a></li>
261<li><a href="#BOOST_QVM_INLINE_CRITICAL"><code>INLINE_CRITICAL</code></a></li>
262<li><a href="#BOOST_QVM_INLINE_OPERATIONS"><code>INLINE_OPERATIONS</code></a></li>
263<li><a href="#BOOST_QVM_INLINE_RECURSION"><code>INLINE_RECURSION</code></a></li>
264<li><a href="#BOOST_QVM_ASSERT"><code>ASSERT</code></a></li>
265<li><a href="#BOOST_QVM_STATIC_ASSERT"><code>STATIC_ASSERT</code></a></li>
266<li><a href="#BOOST_QVM_THROW_EXCEPTION"><code>THROW_EXCEPTION</code></a></li>
267</ul>
268</li>
269</ul>
270</li>
271<li><a href="#rationale">Design Rationale</a></li>
272<li><a href="#_code_generator">Code Generator</a></li>
273<li><a href="#_known_quirks_and_issues">Known Quirks and Issues</a>
274<ul class="sectlevel2">
275<li><a href="#_capturing_view_proxies_with_auto">Capturing View Proxies with <code>auto</code></a></li>
276<li><a href="#_binding_qvm_overloads_from_an_unrelated_namespace">Binding QVM Overloads From an Unrelated Namespace</a></li>
277<li><a href="#_link_errors_when_calling_math_functions_with_int_arguments">Link Errors When Calling Math Functions with <code>int</code> Arguments</a></li>
278</ul>
279</li>
280<li><a href="#_distribution">Distribution</a></li>
281<li><a href="#_portability">Portability</a></li>
282<li><a href="#_feedback_support">Feedback / Support</a></li>
283<li><a href="#_qa">Q&amp;A</a></li>
284</ul>
285</div>
286</div>
287<div id="content">
288<div id="preamble">
289<div class="sectionbody">
290<div class="paragraph text-right">
291<p><a href="https://github.com/boostorg/qvm">GitHub</a> | <a href="./qvm.pdf">PDF</a></p>
292</div>
293</div>
294</div>
295<div class="sect1">
296<h2 id="_abstract">Abstract</h2>
297<div class="sectionbody">
298<div class="paragraph">
299<p>QVM is a generic library for working with Quaternions, Vectors and Matrices of static size. Features:</p>
300</div>
301<div class="exampleblock">
302<div class="content">
303<div class="ulist">
304<ul>
305<li>
306<p>Emphasis on 2, 3 and 4-dimensional operations needed in graphics, video games and simulation applications.</p>
307</li>
308<li>
309<p>Free function templates operate on any compatible user-defined quaternion, vector or matrix type.</p>
310</li>
311<li>
312<p>Quaternion, vector and matrix types from different libraries or subsystems can be safely mixed in the same expression.</p>
313</li>
314<li>
315<p>Type-safe mapping between compatible lvalue types with no temporary objects; e.g. transpose remaps the elements, rather than transforming the matrix.</p>
316</li>
317</ul>
318</div>
319</div>
320</div>
321<div class="paragraph text-right">
322<p><a href="#tutorial">Tutorial</a> | <a href="#reference">Reference</a> | <a href="#rationale">Design Rationale</a></p>
323</div>
324</div>
325</div>
326<div class="sect1">
327<h2 id="tutorial">Tutorial</h2>
328<div class="sectionbody">
329<div class="sect2">
330<h3 id="_quaternions_vectors_matrices">Quaternions, Vectors, Matrices</h3>
331<div class="paragraph">
332<p>Out of the box QVM defines generic yet simple <a href="#quat"><code>quat</code></a>, <a href="#vec"><code>vec</code></a> and <a href="#mat"><code>mat</code></a> types. For example, the following snippet creates a quaternion object that rotates around the X axis:</p>
333</div>
334<div class="listingblock">
335<div class="content">
336<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">quat&lt;float&gt; rx = rotx_quat(3.14159f);</code></pre>
337</div>
338</div>
339<div class="paragraph">
340<p>Similarly, a matrix that translates by a given vector can be created as follows:</p>
341</div>
342<div class="listingblock">
343<div class="content">
344<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">vec&lt;float,3&gt; v = {0,0,7};
345mat&lt;float,4,4&gt; tr = translation_mat(v);</code></pre>
346</div>
347</div>
348<div class="paragraph">
349<p>The usual quaternion, vector and matrix operations work on these QVM types, however the operations are decoupled from any specific type: they work on any suitable type that has been registered by specializing the <a href="#quat_traits"><code>quat_traits</code></a>, <a href="#vec_traits"><code>vec_traits</code></a> and <a href="#mat_traits"><code>mat_traits</code></a> templates.</p>
350</div>
351<div class="paragraph">
352<p>For example, a user-defined 3D vector type <code>float3</code> can be introduced to QVM as follows:</p>
353</div>
354<div class="listingblock">
355<div class="content">
356<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">struct float3 { float a[3]; };
357
358namespace boost { namespace qvm {
359
360  template &lt;&gt;
361  struct vec_traits&lt;float3&gt; {
362
363    static int const dim=3;
364    typedef float scalar_type;
365
366    template &lt;int I&gt;
367    static inline scalar_type &amp; write_element( float3 &amp; v ) {
368      return v.a[I];
369    }
370
371    template &lt;int I&gt;
372    static inline scalar_type read_element( float3 const &amp; v ) {
373      return v.a[I];
374    }
375
376    static inline scalar_type &amp; write_element_idx( int i, float3 &amp; v ) {
377      return v.a[i];
378    } //optional
379
380    static inline scalar_type read_element_idx( int i, float3 const &amp; v ) {
381      return v.a[i];
382    } //optional
383
384  };
385
386} }</code></pre>
387</div>
388</div>
389<div class="paragraph">
390<p>Equivalently, using the <a href="#vec_traits_defaults"><code>vec_traits_defaults</code></a> template the above can be shortened to:</p>
391</div>
392<div class="listingblock">
393<div class="content">
394<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
395
396  template &lt;&gt;
397  struct vec_traits&lt;float3&gt;: vec_traits_defaults&lt;float3,float,3&gt; {
398
399    template &lt;int I&gt;
400    static inline scalar_type &amp; write_element( float3 &amp; v ) {
401      return v.a[I];
402    }
403
404    static inline scalar_type &amp; write_element_idx( int i, float3 &amp; v ) {
405      return v.a[i];
406    } //optional
407
408  };
409
410} }</code></pre>
411</div>
412</div>
413<div class="paragraph">
414<p>After a similar specialization of the <a href="#mat_traits"><code>mat_traits</code></a> template for a user-defined 3x3 matrix type <code>float33</code>, the full range of vector and matrix operations defined by QVM headers becomes available automatically:</p>
415</div>
416<div class="listingblock">
417<div class="content">
418<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float3 v;
419X(v) = 0;
420Y(v) = 0;
421Z(v) = 7;
422float vmag = mag(v);
423float33 m = rotx_mat&lt;3&gt;(3.14159f);
424float3 vrot = m * v;</code></pre>
425</div>
426</div>
427<div class="paragraph">
428<p>User-defined quaternion types are similarly introduced to QVM by specializing the <a href="#quat_traits"><code>quat_traits</code></a> template.</p>
429</div>
430<hr>
431</div>
432<div class="sect2">
433<h3 id="_c_arrays">C Arrays</h3>
434<div class="paragraph">
435<p>In <a href="#boost/qvm/quat_traits_array.hpp"><code>boost/qvm/quat_traits_array.hpp</code></a>, <a href="#boost/qvm/vec_traits_array.hpp"><code>boost/qvm/vec_traits_array.hpp</code></a> and <a href="#boost/qvm/mat_traits_array.hpp"><code>boost/qvm/mat_traits_array.hpp</code></a> QVM defines appropriate <a href="#quat_traits"><code>quat_traits</code></a>, <a href="#vec_traits"><code>vec_traits</code></a> and <a href="#mat_traits"><code>mat_traits</code></a> specializations that allow QVM functions to operate directly on plain old C arrays:</p>
436</div>
437<div class="listingblock">
438<div class="content">
439<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float v[3] = {0,0,7};
440float3 vrot = rotx_mat&lt;3&gt;(3.14159f) * v;</code></pre>
441</div>
442</div>
443<div class="paragraph">
444<p>Naturally, operator overloads cannot kick in if all elements of an expression are of built-in types. The following is still illegal:</p>
445</div>
446<div class="listingblock">
447<div class="content">
448<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float v[3] = {0,0,7};
449v *= 42;</code></pre>
450</div>
451</div>
452<div class="paragraph">
453<p>The <a href="#vref"><code>vref</code></a> and <a href="#mref"><code>mref</code></a> function templates can be used to work around this issue:</p>
454</div>
455<div class="listingblock">
456<div class="content">
457<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float v[3] = {0,0,7};
458vref(v) *= 42;</code></pre>
459</div>
460</div>
461<hr>
462</div>
463<div class="sect2">
464<h3 id="view_proxy">View proxies</h3>
465<div class="paragraph">
466<p>QVM defines various function templates that provide static mapping between (possibly user-defined) quaternion, vector and matrix types. The example below multiplies column 1 (QVM indexes are always zero-based) of the matrix <code>m</code> by a scalar:</p>
467</div>
468<div class="listingblock">
469<div class="content">
470<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">void multiply_column1( float33 &amp; m, float scalar ) {
471  col&lt;1&gt;(m) *= scalar;
472}</code></pre>
473</div>
474</div>
475<div class="paragraph">
476<p>The expression <a href="#col"><code>col&lt;1&gt;(m)</code></a> is an lvalue of an unspecified 3D vector type that refers to column 1 of <code>m</code>. Note however that this does not create any temporary objects; instead <code>operator*=</code> above works directly with a reference to <code>m</code>.</p>
477</div>
478<div class="paragraph">
479<p>Here is another example, multiplying a transposed view of a matrix by a vector of some user-defined type <code>float3</code>:</p>
480</div>
481<div class="listingblock">
482<div class="content">
483<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float3 v = {0,0,7};
484float3 vrot = transposed(rotx_mat&lt;3&gt;(3.14159f)) * v;</code></pre>
485</div>
486</div>
487<div class="paragraph">
488<p>In general, the various view proxy functions return references of unspecified, non-copyable types that refer to the original object. They can be assigned from or converted to any compatible vector or matrix type.</p>
489</div>
490<hr>
491</div>
492<div class="sect2">
493<h3 id="_swizzling">Swizzling</h3>
494<div class="paragraph">
495<p>QVM allows accessing vector elements by swizzling, exposing vector views of different dimensions, and/or views with reordered elements. The example below rotates <code>v</code> around the X axis, and stores the resulting vector back in <code>v</code> but with the X and Y elements swapped:</p>
496</div>
497<div class="listingblock">
498<div class="content">
499<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float3 v = {0,0,7};
500YXZ(v) = rotx_mat&lt;3&gt;(3.14159f) * v;</code></pre>
501</div>
502</div>
503<div class="paragraph">
504<p>A special case of swizzling provides next-dimension-view of a vector object, adding either 0 or 1 as its last component. Assuming <code>float3</code> is a 3D vector type, and <code>float4</code> is a 4D vector type, the following statements are valid:</p>
505</div>
506<div class="listingblock">
507<div class="content">
508<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float3 v = {0,0,7};
509float4 point = XYZ1(v); //{0,0,7,1}
510float4 vector = XYZ0(v); //{0,0,7,0}</code></pre>
511</div>
512</div>
513<div class="paragraph">
514<p>It is also valid for swizzling to address vector elements more than once:</p>
515</div>
516<div class="listingblock">
517<div class="content">
518<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float3 v = {0,0,7};
519float4 v1 = ZZZZ(v); //{7,7,7,7}</code></pre>
520</div>
521</div>
522<div class="paragraph">
523<p>QVM defines all permutations of <code>X</code>, <code>Y</code>, <code>Z</code>, <code>W</code> for 1D, 2D, 3D and 4D swizzling, plus each dimension defines variants with 0 or 1 used at any position (if 0 or 1 appear at the first position, the swizzling function name begins with underscore, e.g. <code>_1XY</code>).</p>
524</div>
525<div class="paragraph">
526<p>The swizzling syntax can also be used to bind scalars as vectors. For example:</p>
527</div>
528<div class="listingblock">
529<div class="content">
530<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float3 v = _00X(42.0f); //{0,0,42}</code></pre>
531</div>
532</div>
533<hr>
534</div>
535<div class="sect2">
536<h3 id="enable_if">SFINAE/enable_if</h3>
537<div class="paragraph">
538<p>SFINAE stands for Substitution Failure Is Not An Error. This refers to a situation in C&#43;&#43; where an invalid substitution of template parameters (including when those parameters are deduced implicitly as a result of an unqualified call) is not in itself an error.</p>
539</div>
540<div class="paragraph">
541<p>In absence of concepts support, SFINAE can be used to disable function template overloads that would otherwise present a signature that is too generic. More formally, this is supported by the Boost <code>enable_if</code> library.</p>
542</div>
543<div class="paragraph">
544<p>For example, QVM defines <code>operator*</code> overload which works with any user-defined matrix and vector types. The naive approach would be to declare this overload as follows:</p>
545</div>
546<div class="listingblock">
547<div class="content">
548<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">template &lt;class Matrix,class Vector&gt;
549Vector operator*( Matrix const &amp; m, Vector const &amp; v );</code></pre>
550</div>
551</div>
552<div class="paragraph">
553<p>Even if the function definition might contain code that would compile only for <code>Matrix</code> and <code>Vector</code> types, because the function declaration itself is valid, it will participate in overload rezolutions when multiplying objects of any two types whatsoever. This typically renders overload resolutions ambiguous and the compiler (correctly) issues an error.</p>
554</div>
555<div class="paragraph">
556<p>Using <code>enable_if</code>, QVM declares such overloads in a way that preserves their generic signature but only participate in overload resolutions if the passed parameters make sense depending on the semantics of the operation being defined:</p>
557</div>
558<div class="listingblock">
559<div class="content">
560<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">template &lt;class A,class B&gt;
561typename enable_if_c&lt;
562  is_mat&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp; mat_traits&lt;A&gt;::cols==vec_traits&lt;B&gt;::dim, //Condition
563  B&gt;::type //Return type
564operator*( A const &amp; a, B const &amp; b );</code></pre>
565</div>
566</div>
567<div class="paragraph">
568<p>For brevity, function declarations throughout this documentation specify the condition which controls whether they are enabled or not without specifying exactly what <code>enable_if</code> construct is used to achieve this effect.</p>
569</div>
570<hr>
571</div>
572<div class="sect2">
573<h3 id="_interoperability">Interoperability</h3>
574<div class="paragraph">
575<p>An important design goal of QVM is that it works seamlessly with 3rd-party quaternion, vector and matrix types and libraries. Even when such libraries overload the same C&#43;&#43; operators as QVM, it is safe to bring the entire <code>boost::qvm</code> namespace in scope by specifying:</p>
576</div>
577<div class="listingblock">
578<div class="content">
579<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">using namespace boost::qvm;</code></pre>
580</div>
581</div>
582<div class="paragraph">
583<p>The above using directive does not introduce ambiguities with function and operator overloads defined by a 3rd-party library because:</p>
584</div>
585<div class="ulist">
586<ul>
587<li>
588<p>Most <code>boost::qvm</code> function overloads and all operator overloads use SFINAE/<code>enable_if</code>, which makes them "disappear" unless an expression uses types that have the appropriate QVM-specific type traits defined;</p>
589</li>
590<li>
591<p>Whenever such overloads are compatible with a given expression, their signature is extremely generic, which means that any other (user-defined) compatible overload will be a better match in any overload resolution.</p>
592</li>
593</ul>
594</div>
595<div class="admonitionblock note">
596<table>
597<tr>
598<td class="icon">
599<i class="fa icon-note" title="Note"></i>
600</td>
601<td class="content">
602Bringing the entire boost::qvm namespace in scope may introduce ambiguities when accessing types (as opposed to functions) defined by 3rd-party libraries. In that case, you can safely bring namespace <code>boost::qvm::sfinae</code> in scope instead, which contains only function and operator overloads that use SFINAE/<code>enable_if</code>.
603</td>
604</tr>
605</table>
606</div>
607<div class="sect3">
608<h4 id="_specifying_return_types_for_binary_operations">Specifying return types for binary operations</h4>
609<div class="paragraph">
610<p>Bringing the <code>boost::qvm</code> namespace in scope lets you mix vector and matrix types that come from different APIs into a common, type-safe framework. In this case however, it should be considered what types should be returned by binary operations that return an object by value. For example, if you multiply a 3x3 matrix <code>m1</code> of type <code>user_matrix1</code> by a 3x3 matrix <code>m2</code> of type <code>user_matrix2</code>, what type should that operation return?</p>
611</div>
612<div class="paragraph">
613<p>The answer is that by default, QVM returns some kind of compatible matrix type, so it is always safe to write:</p>
614</div>
615<div class="listingblock">
616<div class="content">
617<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">auto &amp; m = m1 * m2;</code></pre>
618</div>
619</div>
620<div class="paragraph">
621<p>However, the type deduced by default converts implicitly to any compatible matrix type, so the following is also valid, at the cost of a temporary:</p>
622</div>
623<div class="listingblock">
624<div class="content">
625<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">user_matrix1 m = m1 * m2;</code></pre>
626</div>
627</div>
628<div class="paragraph">
629<p>While the temporary object can be optimized away by many compilers, it can be avoided altogether by specializing the <a href="#deduce_mat2"><code>deduce_mat2</code></a> template. For example, to specify that multiplying a <code>user_matrix1</code> by a <code>user_matrix2</code> should always produce a <code>user_matrix1</code> object, you could write:</p>
630</div>
631<div class="listingblock">
632<div class="content">
633<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
634
635  template &lt;&gt;
636  struct deduce_mat2&lt;user_matrix1,user_matrix2,3,3&gt; {
637    typedef user_matrix1 type;
638  };
639
640  template &lt;&gt;
641  struct deduce_mat2&lt;user_matrix2,user_matrix1,3,3&gt; {
642    typedef user_matrix1 type;
643  };
644
645} }</code></pre>
646</div>
647</div>
648<div class="admonitionblock warning">
649<table>
650<tr>
651<td class="icon">
652<i class="fa icon-warning" title="Warning"></i>
653</td>
654<td class="content">
655<div class="paragraph">
656<p>Be mindful of potential ODR violation when using <a href="#deduce_quat2"><code>deduce_quat2</code></a>, <a href="#deduce_vec2"><code>deduce_vec2</code></a> and <a href="#deduce_mat2"><code>deduce_mat2</code></a> in independent libraries. For example, this could happen if <code>lib1</code> defines <code>deduce_vec2&lt;lib1::vec,lib2::vec&gt;::type</code> as <code>lib1::vec</code> and in the same program <code>lib2</code> defines <code>deduce_vec2&lt;lib1::vec,lib2::vec&gt;::type</code> as <code>lib2::vec</code>.</p>
657</div>
658<div class="paragraph">
659<p>It is best to keep such specializations out of <code>lib1</code> and <code>lib2</code>. Of course, it is always safe for <code>lib1</code> and <code>lib2</code> to use <a href="#convert_to"><code>convert_to</code></a> to convert between the <code>lib1::vec</code> and <code>lib2::vec</code> types as needed.</p>
660</div>
661</td>
662</tr>
663</table>
664</div>
665</div>
666<div class="sect3">
667<h4 id="_specifying_return_types_for_unary_operations">Specifying return types for unary operations</h4>
668<div class="paragraph">
669<p>Perhaps surprisingly, unary operations that return an object by value have a similar, though simpler issue. That&#8217;s because the argument they&#8217;re called with may not be copyable, as in:</p>
670</div>
671<div class="listingblock">
672<div class="content">
673<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">float m[3][3];
674auto &amp; inv = inverse(m);</code></pre>
675</div>
676</div>
677<div class="paragraph">
678<p>Above, the object returned by <a href="#mat_inverse"><code>inverse</code></a> and captured by <code>inv</code> can not be of type <code>float[3][3]</code>, because that type isn&#8217;t copyable. By default, QVM "just works", returning an object of suitable matrix type that is copyable. This deduction process can be controlled, by specializing the <a href="#deduce_mat"><code>deduce_mat</code></a> template.</p>
679</div>
680</div>
681<div class="sect3">
682<h4 id="_converting_between_different_quaternion_vector_and_matrix_types">Converting between different quaternion, vector and matrix types</h4>
683<div class="paragraph">
684<p>Any time you need to create a matrix of a particular C&#43;&#43; type from any other compatible matrix type, you can use the <a href="#convert_to"><code>convert_to</code></a> function:</p>
685</div>
686<div class="listingblock">
687<div class="content">
688<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">user_matrix2 m=convert_to&lt;user_matrix2&gt;(m1 * m2);</code></pre>
689</div>
690</div>
691</div>
692</div>
693</div>
694</div>
695<div class="sect1">
696<h2 id="reference">Reference</h2>
697<div class="sectionbody">
698<div class="sect2">
699<h3 id="_header_files">Header Files</h3>
700<div class="paragraph">
701<p>QVM is split into multiple headers to allow different compilation units to <code>#include</code> only the components they need. Each function in this document specifies the exact header that must be <code>#included</code> in order to use it.</p>
702</div>
703<div class="paragraph">
704<p>The tables below list commonly used components and the headers they&#8217;re found in. Header names containing a number define functions that only work with objects of that dimension; e.g. <code>vec_operations2.hpp</code> contains only functions for working with 2D vectors.</p>
705</div>
706<div class="paragraph">
707<p>The header <code>boost/qvm/all.hpp</code> is provided for convenience. It includes all other QVM headers.</p>
708</div>
709<table class="tableblock frame-all grid-all stretch">
710<caption class="title">Table 1. Quaternion header files</caption>
711<colgroup>
712<col style="width: 33.3333%;">
713<col style="width: 66.6667%;">
714</colgroup>
715<tbody>
716<tr>
717<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion traits</p></td>
718<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/quat_traits.hpp&gt;
719#include &lt;boost/qvm/quat_traits_array.hpp&gt;
720#include &lt;boost/qvm/deduce_quat.hpp&gt;</pre></div></td>
721</tr>
722<tr>
723<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion element access</p></td>
724<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/quat_access.hpp&gt;</pre></div></td>
725</tr>
726<tr>
727<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion operations</p></td>
728<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/quat_operations.hpp&gt;</pre></div></td>
729</tr>
730<tr>
731<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#quat"><code>quat</code></a> class template</p></td>
732<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/quat.hpp&gt;</pre></div></td>
733</tr>
734</tbody>
735</table>
736<table class="tableblock frame-all grid-all stretch">
737<caption class="title">Table 2. Vector header files</caption>
738<colgroup>
739<col style="width: 33.3333%;">
740<col style="width: 66.6667%;">
741</colgroup>
742<tbody>
743<tr>
744<td class="tableblock halign-left valign-top"><p class="tableblock">Vector traits</p></td>
745<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/vec_traits.hpp&gt;
746#include &lt;boost/qvm/vec_traits_array.hpp&gt;
747#include &lt;boost/qvm/deduce_vec.hpp&gt;</pre></div></td>
748</tr>
749<tr>
750<td class="tableblock halign-left valign-top"><p class="tableblock">Vector element access</p></td>
751<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/vec_access.hpp&gt;</pre></div></td>
752</tr>
753<tr>
754<td class="tableblock halign-left valign-top"><p class="tableblock">Vector <a href="#swizzling">swizzling</a></p></td>
755<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/swizzle.hpp&gt;
756#include &lt;boost/qvm/swizzle2.hpp&gt;
757#include &lt;boost/qvm/swizzle3.hpp&gt;
758#include &lt;boost/qvm/swizzle4.hpp&gt;</pre></div></td>
759</tr>
760<tr>
761<td class="tableblock halign-left valign-top"><p class="tableblock">Vector operations</p></td>
762<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/vec_operations.hpp&gt;
763#include &lt;boost/qvm/vec_operations2.hpp&gt;
764#include &lt;boost/qvm/vec_operations3.hpp&gt;
765#include &lt;boost/qvm/vec_operations4.hpp&gt;</pre></div></td>
766</tr>
767<tr>
768<td class="tableblock halign-left valign-top"><p class="tableblock">Quaternion-vector operations</p></td>
769<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/quat_vec_operations.hpp&gt;</pre></div></td>
770</tr>
771<tr>
772<td class="tableblock halign-left valign-top"><p class="tableblock">Vector-matrix operations</p></td>
773<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/vec_mat_operations.hpp&gt;</pre></div></td>
774</tr>
775<tr>
776<td class="tableblock halign-left valign-top"><p class="tableblock">Vector-matrix <a href="#view_proxy">view proxies</a></p></td>
777<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/map_vec_mat.hpp&gt;</pre></div></td>
778</tr>
779<tr>
780<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#vec"><code>vec</code></a> class template</p></td>
781<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/vec.hpp&gt;</pre></div></td>
782</tr>
783</tbody>
784</table>
785<table class="tableblock frame-all grid-all stretch">
786<caption class="title">Table 3. Matrix header files</caption>
787<colgroup>
788<col style="width: 33.3333%;">
789<col style="width: 66.6667%;">
790</colgroup>
791<tbody>
792<tr>
793<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix traits</p></td>
794<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/mat_traits.hpp&gt;
795#include &lt;boost/qvm/mat_traits_array.hpp&gt;
796#include &lt;boost/qvm/deduce_mat.hpp&gt;</pre></div></td>
797</tr>
798<tr>
799<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix element access</p></td>
800<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/mat_access.hpp&gt;</pre></div></td>
801</tr>
802<tr>
803<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix operations</p></td>
804<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/mat_operations.hpp&gt;
805#include &lt;boost/qvm/mat_operations2.hpp&gt;
806#include &lt;boost/qvm/mat_operations3.hpp&gt;
807#include &lt;boost/qvm/mat_operations4.hpp&gt;</pre></div></td>
808</tr>
809<tr>
810<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix-matrix <a href="#view_proxy">view proxies</a></p></td>
811<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/map_mat_mat.hpp&gt;</pre></div></td>
812</tr>
813<tr>
814<td class="tableblock halign-left valign-top"><p class="tableblock">Matrix-vector <a href="#view_proxy">view proxies</a></p></td>
815<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/map_mat_vec.hpp&gt;</pre></div></td>
816</tr>
817<tr>
818<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#mat"><code>mat</code></a> class template</p></td>
819<td class="tableblock halign-left valign-top"><div class="literal"><pre>#include &lt;boost/qvm/mat.hpp&gt;</pre></div></td>
820</tr>
821</tbody>
822</table>
823</div>
824<div class="sect2">
825<h3 id="type_traits">Type Traits System</h3>
826<div class="paragraph">
827<p>QVM is designed to work with user-defined quaternion, vector and matrix types, as well as user-defined scalar types. This section formally defines the way such types can be integrated.</p>
828</div>
829<hr>
830<div class="sect3">
831<h4 id="scalar_requirements">Scalar Requirements</h4>
832<div class="paragraph">
833<p>A valid scalar type <code>S</code> must have accessible destructor, default constructor, copy constructor and assignment operator, and must support the following operations:</p>
834</div>
835<div class="listingblock">
836<div class="content">
837<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">S operator*( S, S );
838S operator/( S, S );
839S operator+( S, S );
840S operator-( S, S );
841
842S &amp; operator*=( S &amp;, S );
843S &amp; operator/=( S &amp;, S );
844S &amp; operator+=( S &amp;, S );
845S &amp; operator-=( S &amp;, S );
846
847bool operator==( S, S );
848bool operator!=( S, S );</code></pre>
849</div>
850</div>
851<div class="paragraph">
852<p>In addition, the expression <code>S(0)</code> should construct a scalar of value zero, and <code>S(1)</code> should construct a scalar of value one, or else the <a href="#scalar_traits"><code>scalar_traits</code></a> template must be specialized appropriately.</p>
853</div>
854<hr>
855</div>
856<div class="sect3">
857<h4 id="is_scalar"><code>is_scalar</code></h4>
858<div class="listingblock">
859<div class="title">#include &lt;boost/qvm/scalar_traits.hpp&gt;</div>
860<div class="content">
861<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
862
863  template &lt;class T&gt;
864  struct is_scalar {
865    static bool const value=false;
866  };
867
868  template &lt;&gt; struct is_scalar&lt;char&gt;           { static bool const value=true; };
869  template &lt;&gt; struct is_scalar&lt;signed char&gt;    { static bool const value=true; };
870  template &lt;&gt; struct is_scalar&lt;unsigned char&gt;  { static bool const value=true; };
871  template &lt;&gt; struct is_scalar&lt;signed short&gt;   { static bool const value=true; };
872  template &lt;&gt; struct is_scalar&lt;unsigned short&gt; { static bool const value=true; };
873  template &lt;&gt; struct is_scalar&lt;signed int&gt;     { static bool const value=true; };
874  template &lt;&gt; struct is_scalar&lt;unsigned int&gt;   { static bool const value=true; };
875  template &lt;&gt; struct is_scalar&lt;signed long&gt;    { static bool const value=true; };
876  template &lt;&gt; struct is_scalar&lt;unsigned long&gt;  { static bool const value=true; };
877  template &lt;&gt; struct is_scalar&lt;float&gt;          { static bool const value=true; };
878  template &lt;&gt; struct is_scalar&lt;double&gt;         { static bool const value=true; };
879  template &lt;&gt; struct is_scalar&lt;long double&gt;    { static bool const value=true; };
880
881} }</code></pre>
882</div>
883</div>
884<div class="paragraph">
885<p>This template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a valid scalar type. It must be specialized together with the <a href="#scalar_traits"><code>scalar_traits</code></a> template in order to introduce a user-defined scalar type to QVM. Such types must satisfy the <a href="#scalar_requirements">scalar requirements</a>.</p>
886</div>
887<hr>
888</div>
889<div class="sect3">
890<h4 id="scalar_traits"><code>scalar_traits</code></h4>
891<div class="listingblock">
892<div class="title">#include &lt;boost/qvm/scalar_traits.hpp&gt;</div>
893<div class="content">
894<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
895
896  template &lt;class Scalar&gt;
897  struct scalar_traits {
898
899    BOOST_QVM_INLINE_CRITICAL
900    static Scalar value( int v ) {
901      return Scalar(v);
902    }
903
904  };
905
906} }</code></pre>
907</div>
908</div>
909<div class="paragraph">
910<p>This template may be specialized for user-defined scalar types to define the appropriate conversion from <code>int</code>; this is primarily used whenever QVM needs to deduce a zero or one value.</p>
911</div>
912<hr>
913</div>
914<div class="sect3">
915<h4 id="deduce_scalar"><code>deduce_scalar</code></h4>
916<div class="listingblock">
917<div class="title">#include &lt;boost/qvm/deduce_scalar.hpp&gt;</div>
918<div class="content">
919<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
920
921  template &lt;class A,class B&gt;
922  struct deduce_scalar
923  {
924    typedef typename impl&lt;A,B&gt;::type type;
925  };
926
927} }</code></pre>
928</div>
929</div>
930<div class="dlist">
931<dl>
932<dt class="hdlist1">Requires: </dt>
933<dd>
934<p><code>A</code> and <code>B</code> satisfy the <a href="#scalar_requirements">scalar requirements</a>.</p>
935</dd>
936<dt class="hdlist1">Returns: </dt>
937<dd>
938<p>If <code>A</code> and <code>B</code> are the same type, <code>impl&lt;A,B&gt;::type</code> returns that type. Otherwise, <code>impl&lt;A,B&gt;::type</code> is well defined for the following types only: <code>signed</code>/<code>unsigned char</code>, <code>signed</code>/<code>unsigned short</code>, <code>signed</code>/<code>unsigned int</code>, <code>signed</code>/<code>unsigned long</code>, <code>float</code> and <code>double</code>. The deduction logic is as follows:</p>
939<div class="ulist">
940<ul>
941<li>
942<p>if either of <code>A</code> and <code>B</code> is <code>double</code>, the result is <code>double</code>;</p>
943</li>
944<li>
945<p>else, if one of <code>A</code> or <code>B</code> is an integer type and the other is <code>float</code>, the result is <code>float</code>;</p>
946</li>
947<li>
948<p>else, if one of <code>A</code> or <code>B</code> is a signed integer and the other type is unsigned integer, the signed type is changed to unsigned, and then the lesser of the two integers is promoted to the other.</p>
949</li>
950</ul>
951</div>
952</dd>
953</dl>
954</div>
955<div class="admonitionblock note">
956<table>
957<tr>
958<td class="icon">
959<i class="fa icon-note" title="Note"></i>
960</td>
961<td class="content">
962This template is used by generic binary operations that return a scalar, to deduce the return type based on the (possibly different) scalars of their arguments.
963</td>
964</tr>
965</table>
966</div>
967<hr>
968</div>
969<div class="sect3">
970<h4 id="scalar"><code>scalar</code></h4>
971<div class="listingblock">
972<div class="title">#include &lt;boost/qvm/scalar_traits.hpp&gt;</div>
973<div class="content">
974<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
975
976  template &lt;class T&gt;
977  struct scalar {
978    typedef /*exact definition unspecified*/ type;
979  };
980
981} }</code></pre>
982</div>
983</div>
984<div class="paragraph">
985<p>The expression <a href="#quat_traits"><code>quat_traits&lt;T&gt;::scalar_type</code></a> evaluates to the scalar type of the quaternion type <code>T</code> (if <a href="#is_quat"><code>is_quat&lt;T&gt;::value</code></a> is <code>true</code>).</p>
986</div>
987<div class="paragraph">
988<p>The expression <a href="#vec_traits"><code>vec_traits&lt;T&gt;::scalar_type</code></a> evaluates to the scalar type of the vector type <code>T</code> (if <a href="#is_vec"><code>is_vec&lt;T&gt;::value</code></a> is <code>true</code>).</p>
989</div>
990<div class="paragraph">
991<p>The expression <a href="#mat_traits"><code>mat_traits&lt;T&gt;::scalar_type</code></a> evaluates to the scalar type of the matrix type <code>T</code> (if <a href="#is_mat"><code>is_mat&lt;T&gt;::value</code></a> is <code>true</code>).</p>
992</div>
993<div class="paragraph">
994<p>The expression <code>scalar&lt;T&gt;::type</code> is similar, except that it automatically detects whether <code>T</code> is a vector or a matrix or a quaternion type.</p>
995</div>
996<hr>
997</div>
998<div class="sect3">
999<h4 id="is_quat"><code>is_quat</code></h4>
1000<div class="listingblock">
1001<div class="title">#include &lt;boost/qvm/quat_traits.hpp&gt;</div>
1002<div class="content">
1003<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1004
1005  template &lt;class T&gt;
1006  struct is_quat {
1007
1008    static bool const value = false;
1009
1010  };
1011
1012} }</code></pre>
1013</div>
1014</div>
1015<div class="paragraph">
1016<p>This type template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a quaternion type. For quaternion types, the <a href="#quat_traits"><code>quat_traits</code></a> template can be used to access their elements generically, or to obtain their <code>scalar type</code>.</p>
1017</div>
1018<hr>
1019</div>
1020<div class="sect3">
1021<h4 id="quat_traits"><code>quat_traits</code></h4>
1022<div class="listingblock">
1023<div class="title">#include &lt;boost/qvm/quat_traits.hpp&gt;</div>
1024<div class="content">
1025<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1026
1027  template &lt;class Q&gt;
1028  struct quat_traits {
1029
1030    /*main template members unspecified*/
1031
1032  };
1033
1034  /*
1035  User-defined (possibly partial) specializations:
1036
1037  template &lt;&gt;
1038  struct quat_traits&lt;Q&gt; {
1039
1040    typedef &lt;&lt;user-defined&gt;&gt; scalar_type;
1041
1042    template &lt;int I&gt;
1043    static inline scalar_type read_element( Quaternion const &amp; q );
1044
1045    template &lt;int I&gt;
1046    static inline scalar_type &amp; write_element( Quaternion &amp; q );
1047
1048  };
1049  */
1050
1051} }</code></pre>
1052</div>
1053</div>
1054<div class="paragraph">
1055<p>The <code>quat_traits</code> template must be specialized for (user-defined) quaternion types in order to enable quaternion operations defined in QVM headers for objects of those types.</p>
1056</div>
1057<div class="admonitionblock note">
1058<table>
1059<tr>
1060<td class="icon">
1061<i class="fa icon-note" title="Note"></i>
1062</td>
1063<td class="content">
1064QVM quaternion operations do not require that quaternion types are copyable.
1065</td>
1066</tr>
1067</table>
1068</div>
1069<div class="paragraph">
1070<p>The main <code>quat_traits</code> template members are not specified. Valid specializations are required to define the following members:</p>
1071</div>
1072<div class="ulist">
1073<ul>
1074<li>
1075<p><code>scalar_type</code>: the expression <code>quat_traits&lt;Quaternion&gt;::scalar_type</code> must be a value type which satisfies the <a href="#scalar_requirements"><code>scalar requirements</code></a>.</p>
1076</li>
1077</ul>
1078</div>
1079<div class="paragraph">
1080<p>In addition, valid specializations of the <code>quat_traits</code> template must define at least one of the following access functions as static members, where <code>q</code> is an object of type <code>Quaternion</code>, and <code>I</code> is compile-time integer constant:</p>
1081</div>
1082<div class="ulist">
1083<ul>
1084<li>
1085<p><code>read_element</code>: the expression <code>quat_traits&lt;Quaternion&gt;::read_element&lt;I&gt;(q)</code> returns either a copy of or a <code>const</code> reference to the <code>I</code>-th element of <code>q</code>.</p>
1086</li>
1087<li>
1088<p><code>write_element</code>: the expression <code>quat_traits&lt;Quaternion&gt;::write_element&lt;I&gt;(q)</code> returns mutable reference to the <code>I</code>-th element of <code>q</code>.</p>
1089</li>
1090</ul>
1091</div>
1092<div class="admonitionblock note">
1093<table>
1094<tr>
1095<td class="icon">
1096<i class="fa icon-note" title="Note"></i>
1097</td>
1098<td class="content">
1099For the quaternion <code>a + bi + cj + dk</code>, the elements are assumed to be in the following order: <code>a</code>, <code>b</code>, <code>c</code>, <code>d</code>; that is, <code>I</code>=<code>0</code>/<code>1</code>/<code>2</code>/<code>3</code> would access <code>a</code>/<code>b</code>/<code>c</code>/<code>d</code>.
1100</td>
1101</tr>
1102</table>
1103</div>
1104<div class="paragraph">
1105<p>It is illegal to call any of the above functions unless <code>is_quat&lt;Quaternion&gt;::value</code> is true. Even then, quaternion types are allowed to define only a subset of the access functions.</p>
1106</div>
1107<div class="paragraph">
1108<p>Below is an example of a user-defined quaternion type, and its corresponding specialization of the quat_traits template:</p>
1109</div>
1110<div class="listingblock">
1111<div class="content">
1112<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">#include &lt;boost/qvm/quat_traits.hpp&gt;
1113
1114struct fquat { float a[4]; };
1115
1116namespace boost { namespace qvm {
1117
1118  template &lt;&gt;
1119  struct quat_traits&lt;fquat&gt; {
1120
1121    typedef float scalar_type;
1122
1123    template &lt;int I&gt;
1124    static inline scalar_type &amp; write_element( fquat &amp; q ) {
1125      return q.a[I];
1126    }
1127
1128    template &lt;int I&gt;
1129    static inline scalar_type read_element( fquat const &amp; q ) {
1130      return q.a[I];
1131    }
1132
1133  };
1134
1135} }</code></pre>
1136</div>
1137</div>
1138<div class="paragraph">
1139<p>Equivalently, using the <a href="#quat_traits_defaults"><code>quat_traits_defaults</code></a> template the above can be shortened to:</p>
1140</div>
1141<div class="listingblock">
1142<div class="content">
1143<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1144
1145  template &lt;&gt;
1146  struct quat_traits&lt;fquat&gt;: quat_traits_defaults&lt;fquat,float&gt; {
1147
1148    template &lt;int I&gt;
1149    static inline scalar_type &amp; write_element( fquat &amp; q ) {
1150      return q.a[I];
1151    }
1152
1153  };
1154
1155} }</code></pre>
1156</div>
1157</div>
1158<hr>
1159</div>
1160<div class="sect3">
1161<h4 id="quat_traits_defaults"><code>quat_traits_defaults</code></h4>
1162<div class="listingblock">
1163<div class="title">#include &lt;boost/qvm/quat_traits_defaults.hpp&gt;</div>
1164<div class="content">
1165<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1166
1167  template &lt;class QuatType,class ScalarType&gt;
1168  struct quat_traits_defaults {
1169
1170    typedef QuatType quat_type;
1171
1172    typedef ScalarType scalar_type;
1173
1174    template &lt;int I&gt;
1175    static BOOST_QVM_INLINE_CRITICAL
1176    scalar_type read_element( quat_type const &amp; x ) {
1177      return quat_traits&lt;quat_type&gt;::template
1178        write_element&lt;I&gt;(const_cast&lt;quat_type &amp;&gt;(x));
1179    }
1180
1181  };
1182
1183} }</code></pre>
1184</div>
1185</div>
1186<div class="paragraph">
1187<p>The <code>quat_traits_defaults</code> template is designed to be used as a public base for user-defined specializations of the <a href="#quat_traits"><code>quat_traits</code></a> template, to easily define the required members. If it is used, the only member that must be defined by the user in a <code>quat_traits</code> specialization is <code>write_element</code>; the <code>quat_traits_defaults</code> base will define <code>read_element</code>, as well as <code>scalar_type</code> automatically.</p>
1188</div>
1189<hr>
1190</div>
1191<div class="sect3">
1192<h4 id="deduce_quat"><code>deduce_quat</code></h4>
1193<div class="listingblock">
1194<div class="title">#include &lt;boost/qvm/deduce_quat.hpp&gt;</div>
1195<div class="content">
1196<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1197
1198  template &lt;class Q&gt;
1199  struct deduce_quat {
1200    typedef Q type;
1201  };
1202
1203} }</code></pre>
1204</div>
1205</div>
1206<div class="dlist">
1207<dl>
1208<dt class="hdlist1">Requires: </dt>
1209<dd>
1210<div class="ulist">
1211<ul>
1212<li>
1213<p><code><a href="#is_quat">is_quat</a>&lt;Q&gt;::value</code> is <code>true</code>;</p>
1214</li>
1215<li>
1216<p><code><a href="#is_quat">is_quat</a>&lt;deduce_quat&lt;Q&gt;::type&gt;::value</code> must be <code>true</code>;</p>
1217</li>
1218<li>
1219<p><code>deduce_quat&lt;Q&gt;::type</code> must be copyable.</p>
1220</li>
1221</ul>
1222</div>
1223</dd>
1224</dl>
1225</div>
1226<div class="paragraph">
1227<p>This template is used by QVM whenever it needs to deduce a copyable quaternion type from a single user-supplied function parameter of quaternion type. Note that <code>Q</code> itself may be non-copyable.</p>
1228</div>
1229<div class="paragraph">
1230<p>The main template definition returns <code>Q</code>, which means that it is suitable only for copyable quaternion types. QVM also defines (partial) specializations for the non-copyable quaternion types it produces. Users can define other (partial) specializations for their own types.</p>
1231</div>
1232<div class="paragraph">
1233<p>A typical use of the <code>deduce_quat</code> template is for specifying the preferred quaternion type to be returned by the generic function template overloads in QVM depending on the type of their arguments.</p>
1234</div>
1235<hr>
1236</div>
1237<div class="sect3">
1238<h4 id="deduce_quat2"><code>deduce_quat2</code></h4>
1239<div class="listingblock">
1240<div class="title">#include &lt;boost/qvm/deduce_quat.hpp&gt;</div>
1241<div class="content">
1242<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1243
1244  template &lt;class A,class B&gt;
1245  struct deduce_quat2 {
1246    typedef /*unspecified*/ type;
1247  };
1248
1249} }</code></pre>
1250</div>
1251</div>
1252<div class="dlist">
1253<dl>
1254<dt class="hdlist1">Requires: </dt>
1255<dd>
1256<div class="ulist">
1257<ul>
1258<li>
1259<p>Both <code><a href="#scalar">scalar</a>&lt;A&gt;::type</code> and <code>scalar&lt;B&gt;::type</code> are well defined;</p>
1260</li>
1261<li>
1262<p><code><a href="#is_quat">is_quat</a>&lt;A&gt;::value</code> || <code>is_quat&lt;B&gt;::value</code> is <code>true</code>;</p>
1263</li>
1264<li>
1265<p><code>is_quat&lt;deduce_quat2&lt;A,B&gt;::type&gt;::value</code> must be <code>true</code>;</p>
1266</li>
1267<li>
1268<p><code>deduce_quat2&lt;A,B&gt;::type</code> must be copyable.</p>
1269</li>
1270</ul>
1271</div>
1272</dd>
1273</dl>
1274</div>
1275<div class="paragraph">
1276<p>This template is used by QVM whenever it needs to deduce a quaternion type from the types of two user-supplied function parameters. The returned type must have accessible copy constructor (the <code>A</code> and <code>B</code> types themselves could be non-copyable, and either one of them may not be a quaternion type.)</p>
1277</div>
1278<div class="paragraph">
1279<p>The main template definition returns an unspecified quaternion type with <a href="#quat_traits"><code>scalar_type</code></a> obtained by <code><a href="#deduce_scalar">deduce_scalar</a>&lt;A,B&gt;::type</code>, except if <code>A</code> and <code>B</code> are the same quaternion type <code>Q</code>, in which case <code>Q</code> is returned, which is only suitable for copyable types. QVM also defines (partial) specializations for the non-copyable quaternion types it produces. Users can define other (partial) specializations for their own types.</p>
1280</div>
1281<div class="paragraph">
1282<p>A typical use of the <code>deduce_quat2</code> template is for specifying the preferred quaternion type to be returned by the generic function template overloads in QVM depending on the type of their arguments.</p>
1283</div>
1284<hr>
1285</div>
1286<div class="sect3">
1287<h4 id="is_vec"><code>is_vec</code></h4>
1288<div class="listingblock">
1289<div class="title">#include &lt;boost/qvm/vec_traits.hpp&gt;</div>
1290<div class="content">
1291<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1292
1293  template &lt;class T&gt;
1294  struct is_vec {
1295
1296    static bool const value = false;
1297
1298  };
1299
1300 } }</code></pre>
1301</div>
1302</div>
1303<div class="paragraph">
1304<p>This type template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a vector type. For vector types, the <a href="#vec_traits"><code>vec_traits</code></a> template can be used to access their elements generically, or to obtain their dimension and <code>scalar type</code>.</p>
1305</div>
1306<hr>
1307</div>
1308<div class="sect3">
1309<h4 id="vec_traits"><code>vec_traits</code></h4>
1310<div class="listingblock">
1311<div class="title">#include &lt;boost/qvm/vec_traits.hpp&gt;</div>
1312<div class="content">
1313<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1314
1315  template &lt;class V&gt;
1316  struct vec_traits {
1317
1318    /*main template members unspecified*/
1319
1320  };
1321
1322  /*
1323  User-defined (possibly partial) specializations:
1324
1325  template &lt;&gt;
1326  struct vec_traits&lt;V&gt; {
1327
1328    static int const dim = &lt;&lt;user-defined&gt;&gt;;
1329
1330    typedef &lt;&lt;user-defined&gt;&gt; scalar_type;
1331
1332    template &lt;int I&gt;
1333    static inline scalar_type read_element( Vector const &amp; v );
1334
1335    template &lt;int I&gt;
1336    static inline scalar_type &amp; write_element( Vector &amp; v );
1337
1338    static inline scalar_type read_element_idx( int i, Vector const &amp; v );
1339    static inline scalar_type &amp; write_element_idx( int i, Vector &amp; v );
1340
1341  };
1342  */
1343
1344} }</code></pre>
1345</div>
1346</div>
1347<div class="paragraph">
1348<p>The <code>vec_traits</code> template must be specialized for (user-defined) vector types in order to enable vector and matrix operations defined in QVM headers for objects of those types.</p>
1349</div>
1350<div class="admonitionblock note">
1351<table>
1352<tr>
1353<td class="icon">
1354<i class="fa icon-note" title="Note"></i>
1355</td>
1356<td class="content">
1357QVM vector operations do not require that vector types are copyable.
1358</td>
1359</tr>
1360</table>
1361</div>
1362<div class="paragraph">
1363<p>The main <code>vec_traits</code> template members are not specified. Valid specializations are required to define the following members:</p>
1364</div>
1365<div class="ulist">
1366<ul>
1367<li>
1368<p><code>dim</code>: the expression <code>vec_traits&lt;Vector&gt;::dim</code> must evaluate to a compile-time integer constant greater than 0 that specifies the vector size.</p>
1369</li>
1370<li>
1371<p><code>scalar_type</code>: the expression <code>vec_traits&lt;Vector&gt;::scalar_type</code> must be a value type which satisfies the <a href="#scalar_requirements"><code>scalar requirements</code></a>.</p>
1372</li>
1373</ul>
1374</div>
1375<div class="paragraph">
1376<p>In addition, valid specializations of the <code>vec_traits</code> template may define the following access functions as static members, where <code>v</code> is an object of type <code>Vector</code>, <code>I</code> is a compile-time integer constant, and <code>i</code> is a variable of type <code>int</code>:</p>
1377</div>
1378<div class="ulist">
1379<ul>
1380<li>
1381<p><code>read_element</code>: the expression <code>vec_traits&lt;Vector&gt;::read_element&lt;I&gt;(v)</code> returns either a copy of or a const reference to the <code>I</code>-th element of <code>v</code>.</p>
1382</li>
1383<li>
1384<p><code>write_element</code>: the expression <code>vec_traits&lt;Vector&gt;::write_element&lt;I&gt;(v)</code> returns mutable reference to the <code>I</code>-th element of <code>v</code>.</p>
1385</li>
1386<li>
1387<p><code>read_element_idx</code>: the expression <code>vec_traits&lt;Vector&gt;::read_element_idx(i,v)</code> returns either a copy of or a <code>const</code> reference to the <code>i</code>-th element of <code>v</code>.</p>
1388</li>
1389<li>
1390<p><code>write_element_idx</code>: the expression <code>vec_traits&lt;Vector&gt;::write_element_idx(i,v)</code> returns mutable reference to the <code>i</code>-th element of <code>v</code>.</p>
1391</li>
1392</ul>
1393</div>
1394<div class="paragraph">
1395<p>It is illegal to call any of the above functions unless <code>is_vec&lt;Vector&gt;::value</code> is true. Even then, vector types are allowed to define only a subset of the access functions. The general requirements are:</p>
1396</div>
1397<div class="ulist">
1398<ul>
1399<li>
1400<p>At least one of <code>read_element</code> or <code>write_element</code> must be defined;</p>
1401</li>
1402<li>
1403<p>If <code>read_element_idx</code> is defined, <code>read_element</code> must also be defined;</p>
1404</li>
1405<li>
1406<p>If <code>write_element_idx</code> is defined, <code>write_element</code> must also be defined.</p>
1407</li>
1408</ul>
1409</div>
1410<div class="paragraph">
1411<p>Below is an example of a user-defined 3D vector type, and its corresponding specialization of the <code>vec_traits</code> template:</p>
1412</div>
1413<div class="listingblock">
1414<div class="content">
1415<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">#include &lt;boost/qvm/vec_traits.hpp&gt;
1416
1417struct float3 { float a[3]; };
1418
1419namespace boost { namespace qvm {
1420
1421  template &lt;&gt;
1422  struct vec_traits&lt;float3&gt; {
1423
1424    static int const dim=3;
1425
1426    typedef float scalar_type;
1427
1428    template &lt;int I&gt;
1429    static inline scalar_type &amp; write_element( float3 &amp; v ) {
1430      return v.a[I];
1431    }
1432
1433    template &lt;int I&gt;
1434    static inline scalar_type read_element( float3 const &amp; v ) {
1435      return v.a[I];
1436    }
1437
1438    static inline scalar_type &amp; write_element_idx( int i, float3 &amp; v ) {
1439      return v.a[i];
1440    } //optional
1441
1442    static inline scalar_type read_element_idx( int i, float3 const &amp; v ) {
1443      return v.a[i];
1444    } //optional
1445
1446  };
1447
1448} }</code></pre>
1449</div>
1450</div>
1451<div class="paragraph">
1452<p>Equivalently, using the <a href="#vec_traits_defaults"><code>vec_traits_defaults</code></a> template the above can be shortened to:</p>
1453</div>
1454<div class="listingblock">
1455<div class="content">
1456<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1457
1458  template &lt;&gt;
1459  struct vec_traits&lt;float3&gt;: vec_traits_defaults&lt;float3,float,3&gt;
1460  {
1461
1462    template &lt;int I&gt;
1463    static inline scalar_type &amp; write_element( float3 &amp; v ) {
1464      return v.a[I];
1465    }
1466
1467    static inline scalar_type &amp; write_element_idx( int i, float3 &amp; v ) {
1468      return v.a[i];
1469    } //optional
1470
1471  };
1472
1473} }</code></pre>
1474</div>
1475</div>
1476<hr>
1477</div>
1478<div class="sect3">
1479<h4 id="vec_traits_defaults"><code>vec_traits_defaults</code></h4>
1480<div class="listingblock">
1481<div class="title">#include &lt;boost/qvm/vec_traits_defaults.hpp&gt;</div>
1482<div class="content">
1483<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1484
1485  template &lt;class VecType,class ScalarType,int Dim&gt;
1486  struct vec_traits_defaults {
1487
1488    typedef VecType vec_type;
1489    typedef ScalarType scalar_type;
1490    static int const dim=Dim;
1491
1492    template &lt;int I&gt;
1493    static BOOST_QVM_INLINE_CRITICAL
1494    scalar_type write_element( vec_type const &amp; x ) {
1495      return vec_traits&lt;vec_type&gt;::template write_element&lt;I&gt;(const_cast&lt;vec_type &amp;&gt;(x));
1496    }
1497
1498    static BOOST_QVM_INLINE_CRITICAL
1499    scalar_type read_element_idx( int i, vec_type const &amp; x ) {
1500      return vec_traits&lt;vec_type&gt;::write_element_idx(i,const_cast&lt;vec_type &amp;&gt;(x));
1501    }
1502
1503    protected:
1504
1505    static BOOST_QVM_INLINE_TRIVIAL
1506    scalar_type &amp; write_element_idx( int i, vec_type &amp; m ) {
1507      /* unspecified */
1508    }
1509  };
1510
1511} }</code></pre>
1512</div>
1513</div>
1514<div class="paragraph">
1515<p>The <code>vec_traits_defaults</code> template is designed to be used as a public base for user-defined specializations of the <a href="#vec_traits"><code>vec_traits</code></a> template, to easily define the required members. If it is used, the only member that must be defined by the user in a <code>vec_traits</code> specialization is <code>write_element</code>; the <code>vec_traits_defaults</code> base will define <code>read_element</code>, as well as <code>scalar_type</code> and <code>dim</code> automatically.</p>
1516</div>
1517<div class="paragraph">
1518<p>Optionally, the user may also define <code>write_element_idx</code>, in which case the <code>vec_traits_defaults</code> base will provide a suitable <code>read_element_idx</code> definition automatically. If not, <code>vec_traits_defaults</code> defines a protected implementation of <code>write_element_idx</code> which may be made publicly available by the deriving <code>vec_traits</code> specialization in case the vector type for which it is being specialized can not be indexed efficiently. This <code>write_element_idx</code> function is less efficient (using meta-programming), implemented in terms of the required user-defined <code>write_element</code>.</p>
1519</div>
1520<hr>
1521</div>
1522<div class="sect3">
1523<h4 id="deduce_vec"><code>deduce_vec</code></h4>
1524<div class="listingblock">
1525<div class="title">#include &lt;boost/qvm/deduce_vec.hpp&gt;</div>
1526<div class="content">
1527<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1528
1529  template &lt;class V, int Dim=vec_traits&lt;Vector&gt;::dim&gt;
1530  struct deduce_vec {
1531
1532    typedef /*unspecified*/ type;
1533
1534  };
1535
1536} }</code></pre>
1537</div>
1538</div>
1539<div class="dlist">
1540<dl>
1541<dt class="hdlist1">Requires: </dt>
1542<dd>
1543<div class="ulist">
1544<ul>
1545<li>
1546<p><code><a href="#is_vec">is_vec</a>&lt;V&gt;::value</code> is <code>true</code>;</p>
1547</li>
1548<li>
1549<p><code>is_vec&lt;deduce_vec&lt;V&gt;::type&gt;::value</code> must be <code>true</code>;</p>
1550</li>
1551<li>
1552<p><code>deduce_vec&lt;V&gt;::type</code> must be copyable;</p>
1553</li>
1554<li>
1555<p><code>vec_traits&lt;deduce_vec&lt;V&gt;::type&gt;::dim==Dim</code>.</p>
1556</li>
1557</ul>
1558</div>
1559</dd>
1560</dl>
1561</div>
1562<div class="paragraph">
1563<p>This template is used by QVM whenever it needs to deduce a copyable vector type of certain dimension from a single user-supplied function parameter of vector type. The returned type must have accessible copy constructor. Note that <code>V</code> may be non-copyable.</p>
1564</div>
1565<div class="paragraph">
1566<p>The main template definition returns an unspecified copyable vector type of size <code>Dim</code>, except if <code><a href="#vec_traits">vec_traits</a>&lt;V&gt;::dim==Dim</code>, in which case it returns <code>V</code>, which is suitable only if <code>V</code> is a copyable type. QVM also defines (partial) specializations for the non-copyable vector types it produces. Users can define other (partial) specializations for their own types.</p>
1567</div>
1568<div class="paragraph">
1569<p>A typical use of the <code>deduce_vec</code> template is for specifying the preferred vector type to be returned by the generic function template overloads in QVM depending on the type of their arguments.</p>
1570</div>
1571<hr>
1572</div>
1573<div class="sect3">
1574<h4 id="deduce_vec2"><code>deduce_vec2</code></h4>
1575<div class="listingblock">
1576<div class="title">#include &lt;boost/qvm/deduce_vec.hpp&gt;</div>
1577<div class="content">
1578<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1579
1580  template &lt;class A,class B,int Dim&gt;
1581  struct deduce_vec2 {
1582    typedef /*unspecified*/ type;
1583  };
1584
1585} }</code></pre>
1586</div>
1587</div>
1588<div class="dlist">
1589<dl>
1590<dt class="hdlist1">Requires: </dt>
1591<dd>
1592<div class="ulist">
1593<ul>
1594<li>
1595<p>Both <code><a href="#scalar">scalar</a>&lt;A&gt;::type</code> and <code>scalar&lt;B&gt;::type</code> are well defined;</p>
1596</li>
1597<li>
1598<p><code><a href="#is_vec">is_vec</a>&lt;A&gt;::value || is_vec&lt;B&gt;::value</code> is <code>true</code>;</p>
1599</li>
1600<li>
1601<p><code>is_vec&lt;deduce_vec2&lt;A,B&gt;::type&gt;::value</code> must be <code>true</code>;</p>
1602</li>
1603<li>
1604<p><code>deduce_vec2&lt;A,B&gt;::type</code> must be copyable;</p>
1605</li>
1606<li>
1607<p><code>vec_traits&lt;deduce_vec2&lt;A,B&gt;::type&gt;::dim==Dim</code>.</p>
1608</li>
1609</ul>
1610</div>
1611</dd>
1612</dl>
1613</div>
1614<div class="paragraph">
1615<p>This template is used by QVM whenever it needs to deduce a vector type of certain dimension from the types of two user-supplied function parameters. The returned type must have accessible copy constructor (the <code>A</code> and <code>B</code> types themselves could be non-copyable, and either one of them may not be a vector type.)</p>
1616</div>
1617<div class="paragraph">
1618<p>The main template definition returns an unspecified vector type of the requested dimension with <a href="#vec_traits"><code>scalar_type</code></a> obtained by <code><a href="#deduce_scalar">deduce_scalar</a>&lt;A,B&gt;::type</code>, except if <code>A</code> and <code>B</code> are the same vector type <code>V</code> of dimension <code>Dim</code>, in which case <code>V</code> is returned, which is only suitable for copyable types. QVM also defines (partial) specializations for the non-copyable vector types it produces. Users can define other (partial) specializations for their own types.</p>
1619</div>
1620<div class="paragraph">
1621<p>A typical use of the <code>deduce_vec2</code> template is for specifying the preferred vector type to be returned by the generic function template overloads in QVM depending on the type of their arguments.</p>
1622</div>
1623<hr>
1624</div>
1625<div class="sect3">
1626<h4 id="is_mat"><code>is_mat</code></h4>
1627<div class="listingblock">
1628<div class="title">#include &lt;boost/qvm/mat_traits.hpp&gt;</div>
1629<div class="content">
1630<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1631
1632  template &lt;class T&gt;
1633  struct is_mat {
1634
1635    static bool const value = false;
1636
1637  };
1638
1639} }</code></pre>
1640</div>
1641</div>
1642<div class="paragraph">
1643<p>This type template defines a compile-time boolean constant value which can be used to determine whether a type <code>T</code> is a matrix type. For matrix types, the <a href="#mat_traits"><code>mat_traits</code></a> template can be used to access their elements generically, or to obtain their dimensions and scalar type.</p>
1644</div>
1645<hr>
1646</div>
1647<div class="sect3">
1648<h4 id="mat_traits"><code>mat_traits</code></h4>
1649<div class="listingblock">
1650<div class="title">#include &lt;boost/qvm/mat_traits.hpp&gt;</div>
1651<div class="content">
1652<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1653
1654  template &lt;class M&gt;
1655  struct mat_traits {
1656
1657    /*main template members unspecified*/
1658
1659  };
1660
1661  /*
1662  User-defined (possibly partial) specializations:
1663
1664  template &lt;&gt;
1665  struct mat_traits&lt;M&gt; {
1666
1667    static int const rows = &lt;&lt;user-defined&gt;&gt;;
1668    static int const cols = &lt;&lt;user-defined&gt;&gt;;
1669    typedef &lt;&lt;user-defined&gt;&gt; scalar_type;
1670
1671    template &lt;int R,int C&gt;
1672    static inline scalar_type read_element( Matrix const &amp; m );
1673
1674    template &lt;int R,int C&gt;
1675    static inline scalar_type &amp; write_element( Matrix &amp; m );
1676
1677    static inline scalar_typeread_element_idx( int r, int c, Matrix const &amp; m );
1678    static inline scalar_type &amp; write_element_idx( int r, int c, Matrix &amp; m );
1679
1680  };
1681  */
1682
1683} }</code></pre>
1684</div>
1685</div>
1686<div class="paragraph">
1687<p>The <code>mat_traits</code> template must be specialized for (user-defined) matrix types in order to enable vector and matrix operations defined in QVM headers for objects of those types.</p>
1688</div>
1689<div class="admonitionblock note">
1690<table>
1691<tr>
1692<td class="icon">
1693<i class="fa icon-note" title="Note"></i>
1694</td>
1695<td class="content">
1696The matrix operations defined by QVM do not require matrix types to be copyable.
1697</td>
1698</tr>
1699</table>
1700</div>
1701<div class="paragraph">
1702<p>The main <code>mat_traits</code> template members are not specified. Valid specializations are required to define the following members:</p>
1703</div>
1704<div class="ulist">
1705<ul>
1706<li>
1707<p><code>rows</code>: the expression <code>mat_traits&lt;Matrix&gt;::rows</code> must evaluate to a compile-time integer constant greater than 0 that specifies the number of rows in a matrix.</p>
1708</li>
1709<li>
1710<p><code>cols</code> must evaluate to a compile-time integer constant greater than 0 that specifies the number of columns in a matrix.</p>
1711</li>
1712<li>
1713<p><code>scalar_type</code>: the expression <code>mat_traits&lt;Matrix&gt;::scalar_type</code> must be a value type which satisfies the scalar requirements.</p>
1714</li>
1715</ul>
1716</div>
1717<div class="paragraph">
1718<p>In addition, valid specializations of the <code>mat_traits</code> template may define the following access functions as static members, where <code>m</code> is an object of type <code>Matrix</code>, <code>R</code> and <code>C</code> are compile-time integer constants, and <code>r</code> and <code>c</code> are variables of type <code>int</code>:</p>
1719</div>
1720<div class="ulist">
1721<ul>
1722<li>
1723<p><code>read_element</code>: the expression <code>mat_traits&lt;Matrix&gt;::read_element&lt;R,C&gt;(m)</code> returns either a copy of or a const reference to the element at row <code>R</code> and column <code>C</code> of <code>m</code>.</p>
1724</li>
1725<li>
1726<p><code>write_element</code>: the expression <code>mat_traits&lt;Matrix&gt;::write_element&lt;R,C&gt;(m)</code> returns mutable reference to the element at row <code>R</code> and column <code>C</code> of <code>m</code>.</p>
1727</li>
1728<li>
1729<p><code>read_element_idx</code>: the expression <code>mat_traits&lt;Matrix&gt;::read_element_idx(r,c,m)</code> returns either a copy of or a const reference to the element at row <code>r</code> and column <code>c</code> of <code>m</code>.</p>
1730</li>
1731<li>
1732<p><code>write_element_idx</code>: the expression <code>mat_traits&lt;Matrix&gt;::write_element_idx(r,c,m)</code> returns mutable reference to the element at row <code>r</code> and column <code>c</code> of <code>m</code>.</p>
1733</li>
1734</ul>
1735</div>
1736<div class="paragraph">
1737<p>It is illegal to call any of the above functions unless <code>is_mat&lt;Matrix&gt;::value</code> is true. Even then, matrix types are allowed to define only a subset of the access functions. The general requirements are:</p>
1738</div>
1739<div class="ulist">
1740<ul>
1741<li>
1742<p>At least one of <code>read_element</code> or <code>write_element</code> must be defined;</p>
1743</li>
1744<li>
1745<p>If <code>read_element_idx</code> is defined, <code>read_element</code> must also be defined;</p>
1746</li>
1747<li>
1748<p>If <code>write_element_idx</code> is defined, <code>write_element</code> must also be defined.</p>
1749</li>
1750</ul>
1751</div>
1752<div class="paragraph">
1753<p>Below is an example of a user-defined 3x3 matrix type, and its corresponding specialization of the <code>mat_traits</code> template:</p>
1754</div>
1755<div class="listingblock">
1756<div class="content">
1757<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">#include &lt;boost/qvm/mat_traits.hpp&gt;
1758
1759struct float33 { float a[3][3]; };
1760
1761namespace boost { namespace qvm {
1762
1763  template &lt;&gt;
1764  struct mat_traits&lt;float33&gt; {
1765
1766    static int const rows=3;
1767    static int const cols=3;
1768    typedef float scalar_type;
1769
1770    template &lt;int R,int C&gt;
1771    static inline scalar_type &amp; write_element( float33 &amp; m ) {
1772      return m.a[R][C];
1773    }
1774
1775    template &lt;int R,int C&gt;
1776    static inline scalar_type read_element( float33 const &amp; m ) {
1777      return m.a[R][C];
1778    }
1779
1780    static inline scalar_type &amp; write_element_idx( int r, int c, float33 &amp; m ) {
1781      return m.a[r][c];
1782    }
1783
1784    static inline scalar_type read_element_idx( int r, int c, float33 const &amp; m ) {
1785      return m.a[r][c];
1786    }
1787
1788  };
1789
1790} }</code></pre>
1791</div>
1792</div>
1793<div class="paragraph">
1794<p>Equivalently, we could use the &lt;&lt;mat_traits_defaults,<code>mat_traits_defaults</code> template to shorten the above to:</p>
1795</div>
1796<div class="listingblock">
1797<div class="content">
1798<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1799
1800  template &lt;&gt;
1801  struct mat_traits&lt;float33&gt;: mat_traits_defaults&lt;float33,float,3,3&gt; {
1802
1803    template &lt;int R,int C&gt; static inline scalar_type &amp; write_element( float33 &amp; m ) { return m.a[R][C]; }
1804
1805    static inline scalar_type &amp; write_element_idx( int r, int c, float33 &amp; m ) {
1806      return m.a[r][c];
1807    }
1808
1809  };
1810
1811} }</code></pre>
1812</div>
1813</div>
1814<hr>
1815</div>
1816<div class="sect3">
1817<h4 id="mat_traits_defaults"><code>mat_traits_defaults</code></h4>
1818<div class="listingblock">
1819<div class="title">#include &lt;boost/qvm/mat_traits_defaults.hpp&gt;</div>
1820<div class="content">
1821<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1822
1823  template &lt;class MatType,class ScalarType,int Rows,int Cols&gt;
1824  struct mat_traits_defaults
1825  {
1826    typedef MatType mat_type;
1827    typedef ScalarType scalar_type;
1828    static int const rows=Rows;
1829    static int const cols=Cols;
1830
1831    template &lt;int Row,int Col&gt;
1832    static BOOST_QVM_INLINE_CRITICAL
1833    scalar_type write_element( mat_type const &amp; x ) {
1834      return mat_traits&lt;mat_type&gt;::template write_element&lt;Row,Col&gt;(const_cast&lt;mat_type &amp;&gt;(x));
1835    }
1836
1837    static BOOST_QVM_INLINE_CRITICAL
1838    scalar_type read_element_idx( int r, int c, mat_type const &amp; x ) {
1839      return mat_traits&lt;mat_type&gt;::write_element_idx(r,c,const_cast&lt;mat_type &amp;&gt;(x));
1840    }
1841
1842    protected:
1843
1844    static BOOST_QVM_INLINE_TRIVIAL
1845    scalar_type &amp; write_element_idx( int r, int c, mat_type &amp; m ) {
1846      /* unspecified */
1847    }
1848  };
1849
1850} }</code></pre>
1851</div>
1852</div>
1853<div class="paragraph">
1854<p>The <code>mat_traits_defaults</code> template is designed to be used as a public base for user-defined specializations of the <a href="#mat_traits"><code>mat_traits</code></a> template, to easily define the required members. If it is used, the only member that must be defined by the user in a <code>mat_traits</code> specialization is <code>write_element</code>; the <code>mat_traits_defaults</code> base will define <code>read_element</code>, as well as <code>scalar_type</code>, <code>rows</code> and <code>cols</code> automatically.</p>
1855</div>
1856<div class="paragraph">
1857<p>Optionally, the user may also define <code>write_element_idx</code>, in which case the <code>mat_traits_defaults</code> base will provide a suitable <code>read_element_idx</code> definition automatically. Otherwise, <code>mat_traits_defaults</code> defines a protected implementation of <code>write_element_idx</code> which may be made publicly available by the deriving <code>mat_traits</code> specialization in case the matrix type for which it is being specialized can not be indexed efficiently. This <code>write_element_idx</code> function is less efficient (using meta-programming), implemented in terms of the required user-defined <code>write_element</code>.</p>
1858</div>
1859<hr>
1860</div>
1861<div class="sect3">
1862<h4 id="deduce_mat"><code>deduce_mat</code></h4>
1863<div class="listingblock">
1864<div class="title">#include &lt;boost/qvm/deduce_mat.hpp&gt;</div>
1865<div class="content">
1866<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1867
1868  template &lt;
1869    class M,
1870    int Rows=mat_traits&lt;Matrix&gt;::rows,
1871    int Cols=mat_traits&lt;Matrix&gt;::cols&gt;
1872  struct deduce_mat {
1873
1874    typedef /*unspecified*/ type;
1875
1876  };
1877
1878} }</code></pre>
1879</div>
1880</div>
1881<div class="dlist">
1882<dl>
1883<dt class="hdlist1">Requires: </dt>
1884<dd>
1885<div class="ulist">
1886<ul>
1887<li>
1888<p><code><a href="#is_mat">is_mat</a>&lt;M&gt;::value</code> is <code>true</code>;</p>
1889</li>
1890<li>
1891<p><code>is_mat&lt;deduce_mat&lt;M&gt;::type&gt;::value</code> must be <code>true</code>;</p>
1892</li>
1893<li>
1894<p><code>deduce_mat&lt;M&gt;::type</code> must be copyable;</p>
1895</li>
1896<li>
1897<p><code><a href="#mat_traits">mat_traits</a>&lt;deduce_mat&lt;M&gt;::type&gt;::rows==Rows</code>;</p>
1898</li>
1899<li>
1900<p><code>mat_traits&lt;deduce_mat&lt;M&gt;::type&gt;::cols==Cols</code>.</p>
1901</li>
1902</ul>
1903</div>
1904</dd>
1905</dl>
1906</div>
1907<div class="paragraph">
1908<p>This template is used by QVM whenever it needs to deduce a copyable matrix type of certain dimensions from a single user-supplied function parameter of matrix type. The returned type must have accessible copy constructor. Note that M itself may be non-copyable.</p>
1909</div>
1910<div class="paragraph">
1911<p>The main template definition returns an unspecified copyable matrix type of size <code>Rows</code> x <code>Cols</code>, except if <code><a href="#mat_traits">mat_traits</a>&lt;M&gt;::rows==Rows &amp;&amp; mat_traits&lt;M&gt;::cols==Cols</code>, in which case it returns <code>M</code>, which is suitable only if <code>M</code> is a copyable type. QVM also defines (partial) specializations for the non-copyable matrix types it produces. Users can define other (partial) specializations for their own types.</p>
1912</div>
1913<div class="paragraph">
1914<p>A typical use of the deduce_mat template is for specifying the preferred matrix type to be returned by the generic function template overloads in QVM depending on the type of their arguments.</p>
1915</div>
1916<hr>
1917</div>
1918<div class="sect3">
1919<h4 id="deduce_mat2"><code>deduce_mat2</code></h4>
1920<div class="listingblock">
1921<div class="title">#include &lt;boost/qvm/deduce_mat.hpp&gt;</div>
1922<div class="content">
1923<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1924
1925  template &lt;class A,class B,int Rows,int Cols&gt;
1926  struct deduce_mat2 {
1927
1928    typedef /*unspecified*/ type;
1929
1930  };
1931
1932} }</code></pre>
1933</div>
1934</div>
1935<div class="dlist">
1936<dl>
1937<dt class="hdlist1">Requires: </dt>
1938<dd>
1939<div class="ulist">
1940<ul>
1941<li>
1942<p>Both <code><a href="#scalar">scalar</a>&lt;A&gt;::type</code> and <code>scalar&lt;B&gt;::type</code> are well defined;</p>
1943</li>
1944<li>
1945<p><code><a href="#is_mat">is_mat</a>&lt;A&gt;::value || is_mat&lt;B&gt;::value</code> is <code>true</code>;</p>
1946</li>
1947<li>
1948<p><code>is_mat&lt;deduce_mat2&lt;A,B&gt;::type&gt;::value</code> must be <code>true</code>;</p>
1949</li>
1950<li>
1951<p><code>deduce_mat2&lt;A,B&gt;::type</code> must be copyable;</p>
1952</li>
1953<li>
1954<p><code><a href="#mat_traits">mat_traits</a>&lt;deduce_mat2&lt;A,B&gt;::type&gt;::rows==Rows</code>;</p>
1955</li>
1956<li>
1957<p><code>mat_traits&lt;deduce_mat2&lt;A,B&gt;::type&gt;::cols==Cols</code>.</p>
1958</li>
1959</ul>
1960</div>
1961</dd>
1962</dl>
1963</div>
1964<div class="paragraph">
1965<p>This template is used by QVM whenever it needs to deduce a matrix type of certain dimensions from the types of two user-supplied function parameters. The returned type must have accessible copy constructor (the <code>A</code> and <code>B</code> types themselves could be non-copyable, and either one of them may be a non-matrix type.)</p>
1966</div>
1967<div class="paragraph">
1968<p>The main template definition returns an unspecified matrix type of the requested dimensions with <a href="#mat_traits"><code>scalar_type</code></a> obtained by <code><a href="#deduce_scalar">deduce_scalar</a>&lt;A,B&gt;::type</code>, except if <code>A</code> and <code>B</code> are the same matrix type <code>M</code> of dimensions <code>Rows</code> x <code>Cols</code>, in which case <code>M</code> is returned, which is only suitable for copyable types. QVM also defines (partial) specializations for the non-copyable matrix types it produces. Users can define other (partial) specializations for their own types.</p>
1969</div>
1970<div class="paragraph">
1971<p>A typical use of the <code>deduce_mat2</code> template is for specifying the preferred matrix type to be returned by the generic function template overloads in QVM depending on the type of their arguments.</p>
1972</div>
1973<hr>
1974</div>
1975</div>
1976<div class="sect2">
1977<h3 id="_built_in_quaternion_vector_and_matrix_types">Built-in Quaternion, Vector and Matrix Types</h3>
1978<div class="paragraph">
1979<p>QVM defines several class templates (together with appropriate specializations of <a href="#quat_traits"><code>quat_traits</code></a>, <a href="#vec_traits"><code>vec_traits</code></a> and <a href="#mat_traits"><code>mat_traits</code></a> templates) which can be used as generic quaternion, vector and matrix types. Using these types directly wouldn&#8217;t be typical though, the main design goal of QVM is to allow users to plug in their own quaternion, vector and matrix types.</p>
1980</div>
1981<div class="sect3">
1982<h4 id="quat"><code>quat</code></h4>
1983<div class="listingblock">
1984<div class="title">#include &lt;boost/qvm/quat.hpp&gt;</div>
1985<div class="content">
1986<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
1987
1988    template &lt;class T&gt;
1989    struct quat {
1990
1991      T a[4];
1992
1993      template &lt;class R&gt;
1994      operator R() const {
1995        R r;
1996        assign(r,*this);
1997        return r;
1998      }
1999
2000    };
2001
2002    template &lt;class Quaternion&gt;
2003    struct quat_traits;
2004
2005    template &lt;class T&gt;
2006    struct quat_traits&lt; quat&lt;T&gt; &gt; {
2007
2008      typedef T scalar_type;
2009
2010      template &lt;int I&gt;
2011      static scalar_type read_element( quat&lt;T&gt; const &amp; x ) {
2012        return x.a[I];
2013      }
2014
2015      template &lt;int I&gt;
2016      static scalar_type &amp; write_element( quat&lt;T&gt; &amp; x ) {
2017        return x.a[I];
2018      }
2019
2020    };
2021
2022} }</code></pre>
2023</div>
2024</div>
2025<div class="paragraph">
2026<p>This is a simple quaternion type. It converts to any other quaternion type.</p>
2027</div>
2028<div class="paragraph">
2029<p>The partial specialization of the <a href="#quat_traits"><code>quat_traits</code></a> template makes the <code>quat</code> template compatible with the generic operations defined by QVM.</p>
2030</div>
2031<hr>
2032</div>
2033<div class="sect3">
2034<h4 id="vec"><code>vec</code></h4>
2035<div class="listingblock">
2036<div class="title">#include &lt;boost/qvm/vec.hpp&gt;</div>
2037<div class="content">
2038<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2039
2040    template &lt;class T,int Dim&gt;
2041    struct vec {
2042
2043      T a[Dim];
2044
2045      template &lt;class R&gt;
2046      operator R() const {
2047        R r;
2048        assign(r,*this);
2049        return r;
2050      }
2051
2052    };
2053
2054    template &lt;class Vector&gt;
2055    struct vec_traits;
2056
2057    template &lt;class T,int Dim&gt;
2058    struct vec_traits&lt; vec&lt;T,Dim&gt; &gt; {
2059
2060      typedef T scalar_type;
2061      static int const dim=Dim;
2062
2063      template &lt;int I&gt;
2064      static scalar_type read_element( vec&lt;T,Dim&gt; const &amp; x ) {
2065        return x.a[I];
2066      }
2067
2068      template &lt;int I&gt;
2069      static scalar_type &amp; write_element( vec&lt;T,Dim&gt; &amp; x ) {
2070        return x.a[I];
2071      }
2072
2073      static scalar_type read_element_idx( int i, vec&lt;T,Dim&gt; const &amp; x ) {
2074        return x.a[i];
2075      }
2076
2077      static scalar_type &amp; write_element_idx( int i, vec&lt;T,Dim&gt; &amp; x ) {
2078        return x.a[i];
2079      }
2080    };
2081
2082} }</code></pre>
2083</div>
2084</div>
2085<div class="paragraph">
2086<p>This is a simple vector type. It converts to any other vector type of compatible size.</p>
2087</div>
2088<div class="paragraph">
2089<p>The partial specialization of the <a href="#vec_traits"><code>vec_traits</code></a> template makes the <code>vec</code> template compatible with the generic operations defined by QVM.</p>
2090</div>
2091<hr>
2092</div>
2093<div class="sect3">
2094<h4 id="mat"><code>mat</code></h4>
2095<div class="listingblock">
2096<div class="title">#include &lt;boost/qvm/mat.hpp&gt;</div>
2097<div class="content">
2098<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2099
2100  template &lt;class T,int Rows,int Cols&gt;
2101  struct mat {
2102
2103    T a[Rows][Cols];
2104
2105    template &lt;class R&gt;
2106    operator R() const {
2107      R r;
2108      assign(r,*this);
2109      return r;
2110    }
2111
2112  };
2113
2114  template &lt;class Matrix&gt;
2115  struct mat_traits;
2116
2117  template &lt;class T,int Rows,int Cols&gt;
2118  struct mat_traits&lt; mat&lt;T,Rows,Cols&gt; &gt; {
2119
2120    typedef T scalar_type;
2121    static int const rows=Rows;
2122    static int const cols=Cols;
2123
2124    template &lt;int Row,int Col&gt;
2125    static scalar_type read_element( mat&lt;T,Rows,Cols&gt; const &amp; x ) {
2126      return x.a[Row][Col];
2127    }
2128
2129    template &lt;int Row,int Col&gt;
2130    static scalar_type &amp; write_element( mat&lt;T,Rows,Cols&gt; &amp; x ) {
2131      return x.a[Row][Col];
2132    }
2133
2134    static scalar_type read_element_idx( int row, int col, mat&lt;T,Rows,Cols&gt; const &amp; x ) {
2135      return x.a[row][col];
2136    }
2137
2138    static scalar_type &amp; write_element_idx( int row, int col, mat&lt;T,Rows,Cols&gt; &amp; x ) {
2139      return x.a[row][col];
2140    }
2141
2142  };
2143
2144} }</code></pre>
2145</div>
2146</div>
2147<div class="paragraph">
2148<p>This is a simple matrix type. It converts to any other matrix type of compatible size.</p>
2149</div>
2150<div class="paragraph">
2151<p>The partial specialization of the <a href="#mat_traits"><code>mat_traits</code></a> template makes the <code>mat</code> template compatible with the generic operations defined by QVM.</p>
2152</div>
2153<hr>
2154</div>
2155</div>
2156<div class="sect2">
2157<h3 id="_element_access">Element Access</h3>
2158<div class="sect3">
2159<h4 id="quat_access">Quaternions</h4>
2160<div class="listingblock">
2161<div class="title">#include &lt;boost/qvm/quat_access.hpp&gt;</div>
2162<div class="content">
2163<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2164
2165  //Only enabled if:
2166  //  is_quat&lt;Q&gt;::value
2167
2168  template &lt;class Q&gt; -unspecified-return-type- S( Q &amp; q );
2169  template &lt;class Q&gt; -unspecified-return-type- V( Q &amp; q );
2170  template &lt;class Q&gt; -unspecified-return-type- X( Q &amp; q );
2171  template &lt;class Q&gt; -unspecified-return-type- Y( Q &amp; q );
2172  template &lt;class Q&gt; -unspecified-return-type- Z( Q &amp; q );
2173
2174} }</code></pre>
2175</div>
2176</div>
2177<div class="paragraph">
2178<p>An expression of the form <code>S(q)</code> can be used to access the scalar component of the quaternion <code>q</code>. For example,</p>
2179</div>
2180<div class="listingblock">
2181<div class="content">
2182<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">S(q) *= 42;</code></pre>
2183</div>
2184</div>
2185<div class="paragraph">
2186<p>multiplies the scalar component of <code>q</code> by the scalar 42.</p>
2187</div>
2188<div class="paragraph">
2189<p>An expression of the form <code>V(q)</code> can be used to access the vector component of the quaternion <code>q</code>. For example,</p>
2190</div>
2191<div class="listingblock">
2192<div class="content">
2193<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">V(q) *= 42</code></pre>
2194</div>
2195</div>
2196<div class="paragraph">
2197<p>multiplies the vector component of <code>q</code> by the scalar 42.</p>
2198</div>
2199<div class="paragraph">
2200<p>The <code>X</code>, <code>Y</code> and <code>Z</code> elements of the vector component can also be accessed directly using <code>X(q)</code>, <code>Y(q)</code> and <code>Z(q)</code>.</p>
2201</div>
2202<div class="admonitionblock tip">
2203<table>
2204<tr>
2205<td class="icon">
2206<i class="fa icon-tip" title="Tip"></i>
2207</td>
2208<td class="content">
2209The return types are lvalues.
2210</td>
2211</tr>
2212</table>
2213</div>
2214</div>
2215<div class="sect3">
2216<h4 id="vec_access">Vectors</h4>
2217<div class="listingblock">
2218<div class="title">#include &lt;boost/qvm/vec_access.hpp&gt;</div>
2219<div class="content">
2220<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2221
2222  //Only enabled if:
2223  //  is_vec&lt;V&gt;::value
2224
2225  template &lt;int I,class V&gt; -unspecified-return-type- A( V &amp; v );
2226  template &lt;class V&gt; -unspecified-return-type- A0( V &amp; v );
2227  template &lt;class V&gt; -unspecified-return-type- A1( V &amp; v );
2228  ...
2229  template &lt;class V&gt; -unspecified-return-type- A9( V &amp; v );
2230
2231  template &lt;class V&gt; -unspecified-return-type- X( V &amp; v );
2232  template &lt;class V&gt; -unspecified-return-type- Y( V &amp; v );
2233  template &lt;class V&gt; -unspecified-return-type- Z( V &amp; v );
2234  template &lt;class V&gt; -unspecified-return-type- W( V &amp; v );
2235
2236} }</code></pre>
2237</div>
2238</div>
2239<div class="paragraph">
2240<p>An expression of the form of <code>A&lt;I&gt;(v)</code> can be used to access the <code>I</code>-th element a vector object <code>v</code>. For example, the expression:</p>
2241</div>
2242<div class="listingblock">
2243<div class="content">
2244<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">A&lt;1&gt;(v) *= 42;</code></pre>
2245</div>
2246</div>
2247<div class="paragraph">
2248<p>can be used to multiply the element at index 1 (indexing in QVM is always zero-based) of a vector <code>v</code> by 42.</p>
2249</div>
2250<div class="paragraph">
2251<p>For convenience, there are also non-template overloads for <code>I</code> from 0 to 9; an alternative way to write the above expression is:</p>
2252</div>
2253<div class="listingblock">
2254<div class="content">
2255<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">A1(v) *= 42;</code></pre>
2256</div>
2257</div>
2258<div class="paragraph">
2259<p><code>X</code>, <code>Y</code>, <code>Z</code> and <code>W</code> act the same as <code>A0</code>/<code>A1</code>/<code>A2</code>/<code>A3</code>; yet another alternative way to write the above expression is:</p>
2260</div>
2261<div class="listingblock">
2262<div class="content">
2263<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">Y(v) *= 42;</code></pre>
2264</div>
2265</div>
2266<div class="admonitionblock tip">
2267<table>
2268<tr>
2269<td class="icon">
2270<i class="fa icon-tip" title="Tip"></i>
2271</td>
2272<td class="content">
2273The return types are lvalues.
2274</td>
2275</tr>
2276</table>
2277</div>
2278</div>
2279<div class="sect3">
2280<h4 id="swizzling">Vector Element Swizzling</h4>
2281<div class="listingblock">
2282<div class="title">#include &lt;boost/qvm/swizzle.hpp&gt;</div>
2283<div class="content">
2284<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2285
2286  //*** Accessing vector elements by swizzling ***
2287
2288  //2D view proxies, only enabled if:
2289  //  is_vec&lt;V&gt;::value
2290  template &lt;class V&gt; -unspecified-2D-vector-type- XX( V &amp; v );
2291  template &lt;class V&gt; -unspecified-2D-vector-type- XY( V &amp; v );
2292  template &lt;class V&gt; -unspecified-2D-vector-type- XZ( V &amp; v );
2293  template &lt;class V&gt; -unspecified-2D-vector-type- XW( V &amp; v );
2294  template &lt;class V&gt; -unspecified-2D-vector-type- X0( V &amp; v );
2295  template &lt;class V&gt; -unspecified-2D-vector-type- X1( V &amp; v );
2296  template &lt;class V&gt; -unspecified-2D-vector-type- YX( V &amp; v );
2297  template &lt;class V&gt; -unspecified-2D-vector-type- YY( V &amp; v );
2298  template &lt;class V&gt; -unspecified-2D-vector-type- YZ( V &amp; v );
2299  template &lt;class V&gt; -unspecified-2D-vector-type- YW( V &amp; v );
2300  template &lt;class V&gt; -unspecified-2D-vector-type- Y0( V &amp; v );
2301  template &lt;class V&gt; -unspecified-2D-vector-type- Y1( V &amp; v );
2302  template &lt;class V&gt; -unspecified-2D-vector-type- ZX( V &amp; v );
2303  template &lt;class V&gt; -unspecified-2D-vector-type- ZY( V &amp; v );
2304  template &lt;class V&gt; -unspecified-2D-vector-type- ZZ( V &amp; v );
2305  template &lt;class V&gt; -unspecified-2D-vector-type- ZW( V &amp; v );
2306  template &lt;class V&gt; -unspecified-2D-vector-type- Z0( V &amp; v );
2307  template &lt;class V&gt; -unspecified-2D-vector-type- Z1( V &amp; v );
2308  template &lt;class V&gt; -unspecified-2D-vector-type- WX( V &amp; v );
2309  template &lt;class V&gt; -unspecified-2D-vector-type- WY( V &amp; v );
2310  template &lt;class V&gt; -unspecified-2D-vector-type- WZ( V &amp; v );
2311  template &lt;class V&gt; -unspecified-2D-vector-type- WW( V &amp; v );
2312  template &lt;class V&gt; -unspecified-2D-vector-type- W0( V &amp; v );
2313  template &lt;class V&gt; -unspecified-2D-vector-type- W1( V &amp; v );
2314  ...
2315  //2D view proxies, only enabled if:
2316  //  is_scalar&lt;S&gt;::value
2317  template &lt;class S&gt; -unspecified-2D-vector-type- X0( S &amp; s );
2318  template &lt;class S&gt; -unspecified-2D-vector-type- X1( S &amp; s );
2319  template &lt;class S&gt; -unspecified-2D-vector-type- XX( S &amp; s );
2320  ...
2321  -unspecified-2D-vector-type- _00();
2322  -unspecified-2D-vector-type- _01();
2323  -unspecified-2D-vector-type- _10();
2324  -unspecified-2D-vector-type- _11();
2325
2326  //3D view proxies, only enabled if:
2327  //  is_vec&lt;V&gt;::value
2328  template &lt;class V&gt; -unspecified-3D-vector-type- XXX( V &amp; v );
2329  ...
2330  template &lt;class V&gt; -unspecified-3D-vector-type- XXW( V &amp; v );
2331  template &lt;class V&gt; -unspecified-3D-vector-type- XX0( V &amp; v );
2332  template &lt;class V&gt; -unspecified-3D-vector-type- XX1( V &amp; v );
2333  template &lt;class V&gt; -unspecified-3D-vector-type- XYX( V &amp; v );
2334  ...
2335  template &lt;class V&gt; -unspecified-3D-vector-type- XY1( V &amp; v );
2336  ...
2337  template &lt;class V&gt; -unspecified-3D-vector-type- WW1( V &amp; v );
2338  ...
2339  //3D view proxies, only enabled if:
2340  //  is_scalar&lt;S&gt;::value
2341  template &lt;class S&gt; -unspecified-3D-vector-type- X00( S &amp; s );
2342  template &lt;class S&gt; -unspecified-3D-vector-type- X01( S &amp; s );
2343  ...
2344  template &lt;class S&gt; -unspecified-3D-vector-type- XXX( S &amp; s );
2345  template &lt;class S&gt; -unspecified-3D-vector-type- XX0( S &amp; s );
2346  ...
2347  -unspecified-3D-vector-type- _000();
2348  -unspecified-3D-vector-type- _001();
2349  -unspecified-3D-vector-type- _010();
2350  ...
2351  -unspecified-3D-vector-type- _111();
2352
2353  //4D view proxies, only enabled if:
2354  //  is_vec&lt;V&gt;::value
2355  template &lt;class V&gt; -unspecified-4D-vector-type- XXXX( V &amp; v );
2356  ...
2357  template &lt;class V&gt; -unspecified-4D-vector-type- XXXW( V &amp; v );
2358  template &lt;class V&gt; -unspecified-4D-vector-type- XXX0( V &amp; v );
2359  template &lt;class V&gt; -unspecified-4D-vector-type- XXX1( V &amp; v );
2360  template &lt;class V&gt; -unspecified-4D-vector-type- XXYX( V &amp; v );
2361  ...
2362  template &lt;class V&gt; -unspecified-4D-vector-type- XXY1( V &amp; v );
2363  ...
2364  template &lt;class V&gt; -unspecified-4D-vector-type- WWW1( V &amp; v );
2365  ...
2366  //4D view proxies, only enabled if:
2367  //  is_scalar&lt;S&gt;::value
2368  template &lt;class S&gt; -unspecified-4D-vector-type- X000( S &amp; s );
2369  template &lt;class S&gt; -unspecified-4D-vector-type- X001( S &amp; s );
2370  ...
2371  template &lt;class S&gt; -unspecified-4D-vector-type- XXXX( S &amp; s );
2372  template &lt;class S&gt; -unspecified-4D-vector-type- XX00( S &amp; s );
2373  ...
2374  -unspecified-4D-vector-type- _0000();
2375  -unspecified-4D-vector-type- _0001();
2376  -unspecified-4D-vector-type- _0010();
2377  ...
2378  -unspecified-4D-vector-type- _1111();
2379
2380} }</code></pre>
2381</div>
2382</div>
2383<div class="paragraph">
2384<p>Swizzling allows zero-overhead direct access to a (possibly rearranged) subset of the elements of 2D, 3D and 4D vectors. For example, if <code>v</code> is a 4D vector, the expression <code>YX(v) is a 2D view proxy whose `X</code> element refers to the <code>Y</code> element of <code>v</code>, and whose <code>Y</code> element refers to the <code>X</code> element of <code>v</code>. Like other view proxies <code>YX</code> is an lvalue, that is, if <code>v2</code> is a 2D vector, one could write:</p>
2385</div>
2386<div class="listingblock">
2387<div class="content">
2388<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">YX(v) = v2;</code></pre>
2389</div>
2390</div>
2391<div class="paragraph">
2392<p>The above will leave the <code>Z</code> and <code>W</code> elements of <code>v</code> unchanged but assign the <code>Y</code> element of <code>v2</code> to the <code>X</code> element of <code>v</code> and the <code>X</code> element of <code>v2</code> to the <code>Y</code> element of <code>v</code>.</p>
2393</div>
2394<div class="paragraph">
2395<p>All permutations of <code>X</code>, <code>Y</code>, <code>Z</code>, <code>W</code>, <code>0</code>, <code>1</code> for 2D, 3D and 4D swizzling are available (if the first character of the swizzle identifier is <code>0</code> or <code>1</code>, it is preceded by a <code>_</code>, for example <code>_11XY</code>).</p>
2396</div>
2397<div class="paragraph">
2398<p>It is valid to use the same vector element more than once: the expression <code>ZZZ(v)</code> is a 3D vector whose <code>X</code>, <code>Y</code> and <code>Z</code> elements all refer to the <code>Z</code> element of <code>v</code>.</p>
2399</div>
2400<div class="paragraph">
2401<p>Finally, scalars can be "swizzled" to access them as vectors: the expression <code>_0X01(42.0f)</code> is a 4D vector with <code>X</code>=0, <code>Y</code>=42.0, <code>Z</code>=0, <code>W</code>=1.</p>
2402</div>
2403</div>
2404<div class="sect3">
2405<h4 id="mat_access">Matrices</h4>
2406<div class="listingblock">
2407<div class="title">#include &lt;boost/qvm/mat_access.hpp&gt;</div>
2408<div class="content">
2409<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2410
2411  //Only enabled if:
2412  //  is_quat&lt;Q&gt;::value
2413
2414  template &lt;int R,int C,class M&gt; -unspecified-return-type- A( M &amp; m );
2415
2416  template &lt;class M&gt; -unspecified-return-type- A00( M &amp; m );
2417  template &lt;class M&gt; -unspecified-return-type- A01( M &amp; m );
2418  ...
2419  template &lt;class M&gt; -unspecified-return-type- A09( M &amp; m );
2420  template &lt;class M&gt; -unspecified-return-type- A10( M &amp; m );
2421  ...
2422  template &lt;class M&gt; -unspecified-return-type- A99( M &amp; m );
2423
2424} }</code></pre>
2425</div>
2426</div>
2427<div class="paragraph">
2428<p>An expression of the form <code>A&lt;R,C&gt;(m)</code> can be used to access the element at row <code>R</code> and column <code>C</code> of a matrix object <code>m</code>. For example, the expression:</p>
2429</div>
2430<div class="listingblock">
2431<div class="content">
2432<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">A&lt;4,2&gt;(m) *= 42;</code></pre>
2433</div>
2434</div>
2435<div class="paragraph">
2436<p>can be used to multiply the element at row 4 and column 2 of a matrix <code>m</code> by 42.</p>
2437</div>
2438<div class="paragraph">
2439<p>For convenience, there are also non-template overloads for <code>R</code> from <code>0</code> to <code>9</code> and <code>C</code> from <code>0</code> to <code>9</code>; an alternative way to write the above expression is:</p>
2440</div>
2441<div class="listingblock">
2442<div class="content">
2443<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">A42(m) *= 42;</code></pre>
2444</div>
2445</div>
2446<div class="admonitionblock tip">
2447<table>
2448<tr>
2449<td class="icon">
2450<i class="fa icon-tip" title="Tip"></i>
2451</td>
2452<td class="content">
2453The return types are lvalues.
2454</td>
2455</tr>
2456</table>
2457</div>
2458<hr>
2459</div>
2460</div>
2461<div class="sect2">
2462<h3 id="_quaternion_operations">Quaternion Operations</h3>
2463<div class="sect3">
2464<h4 id="quat_assign"><code>assign</code></h4>
2465<div class="listingblock">
2466<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2467<div class="content">
2468<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2469
2470  //Only enabled if:
2471  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2472  template &lt;class A,class B&gt;
2473  A &amp; assign( A &amp; a, B const &amp; b );
2474
2475} }</code></pre>
2476</div>
2477</div>
2478<div class="dlist">
2479<dl>
2480<dt class="hdlist1">Effects: </dt>
2481<dd>
2482<p>Copies all elements of the quaternion <code>b</code> to the quaternion <code>a</code>.</p>
2483</dd>
2484<dt class="hdlist1">Returns: </dt>
2485<dd>
2486<p><code>a</code>.</p>
2487</dd>
2488</dl>
2489</div>
2490<hr>
2491</div>
2492<div class="sect3">
2493<h4 id="quat_convert_to"><code>convert_to</code></h4>
2494<div class="listingblock">
2495<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2496<div class="content">
2497<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2498
2499  //Only enabled if:
2500  //  is_quat&lt;R&gt;::value &amp;&amp; is_quat&lt;A&gt;::value
2501  template &lt;class R,class A&gt;
2502  R convert_to( A const &amp; a );
2503
2504  //Only enabled if:
2505  //  is_quat&lt;R&gt;::value &amp;&amp; is_mat&lt;A&gt;::value &amp;&amp;
2506  //  mat_traits&lt;A&gt;::rows==3 &amp;&amp; mat_traits&lt;A&gt;::cols==3
2507  template &lt;class R,class A&gt;
2508  R convert_to( A const &amp; m );
2509
2510} }</code></pre>
2511</div>
2512</div>
2513<div class="dlist">
2514<dl>
2515<dt class="hdlist1">Requires: </dt>
2516<dd>
2517<p><code>R</code> must be copyable.</p>
2518</dd>
2519<dt class="hdlist1">Effects: </dt>
2520<dd>
2521<div class="ulist">
2522<ul>
2523<li>
2524<p>The first overload is equivalent to: <code>R r; assign(r,a); return r;</code></p>
2525</li>
2526<li>
2527<p>The second overload assumes that <code>m</code> is an orthonormal rotation matrix and converts it to a quaternion that performs the same rotation.</p>
2528</li>
2529</ul>
2530</div>
2531</dd>
2532</dl>
2533</div>
2534<hr>
2535</div>
2536<div class="sect3">
2537<h4 id="quat_minus_eq"><code>operator-=</code></h4>
2538<div class="listingblock">
2539<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2540<div class="content">
2541<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2542
2543  //Only enabled if:
2544  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2545  template &lt;class A,class B&gt;
2546  A &amp; operator-=( A &amp; a, B const &amp; b );
2547
2548} }</code></pre>
2549</div>
2550</div>
2551<div class="dlist">
2552<dl>
2553<dt class="hdlist1">Effects: </dt>
2554<dd>
2555<p>Subtracts the elements of <code>b</code> from the corresponding elements of <code>a</code>.</p>
2556</dd>
2557<dt class="hdlist1">Returns: </dt>
2558<dd>
2559<p><code>a</code>.</p>
2560</dd>
2561</dl>
2562</div>
2563<hr>
2564</div>
2565<div class="sect3">
2566<h4 id="quat_minus_unary"><code>operator-</code> (unary)</h4>
2567<div class="listingblock">
2568<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2569<div class="content">
2570<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2571
2572   //Only enabled if: is_quat&lt;A&gt;::value
2573  template &lt;class A&gt;
2574  typename deduce_quat&lt;A&gt;::type
2575  operator-( A const &amp; a );
2576
2577} }</code></pre>
2578</div>
2579</div>
2580<div class="dlist">
2581<dl>
2582<dt class="hdlist1">Returns: </dt>
2583<dd>
2584<p>A quaternion of the negated elements of <code>a</code>.</p>
2585</dd>
2586</dl>
2587</div>
2588<div class="admonitionblock note">
2589<table>
2590<tr>
2591<td class="icon">
2592<i class="fa icon-note" title="Note"></i>
2593</td>
2594<td class="content">
2595The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
2596</td>
2597</tr>
2598</table>
2599</div>
2600<hr>
2601</div>
2602<div class="sect3">
2603<h4 id="quat_minus"><code>operator-</code> (binary)</h4>
2604<div class="listingblock">
2605<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2606<div class="content">
2607<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2608
2609  //Only enabled if:
2610  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2611  template &lt;class A,class B&gt;
2612  typename deduce_quat2&lt;A,B&gt;::type
2613  operator-( A const &amp; a, B const &amp; b );
2614
2615} }</code></pre>
2616</div>
2617</div>
2618<div class="dlist">
2619<dl>
2620<dt class="hdlist1">Returns: </dt>
2621<dd>
2622<p>A quaternion with elements equal to the elements of <code>b</code> subtracted from the corresponding elements of <code>a</code>.</p>
2623</dd>
2624</dl>
2625</div>
2626<div class="admonitionblock note">
2627<table>
2628<tr>
2629<td class="icon">
2630<i class="fa icon-note" title="Note"></i>
2631</td>
2632<td class="content">
2633The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
2634</td>
2635</tr>
2636</table>
2637</div>
2638<hr>
2639</div>
2640<div class="sect3">
2641<h4 id="quat_plus_eq"><code>operator+=</code></h4>
2642<div class="listingblock">
2643<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2644<div class="content">
2645<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2646
2647  //Only enabled if:
2648  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2649  template &lt;class A,class B&gt;
2650  A &amp; operator+=( A &amp; a, B const &amp; b );
2651
2652} }</code></pre>
2653</div>
2654</div>
2655<div class="dlist">
2656<dl>
2657<dt class="hdlist1">Effects: </dt>
2658<dd>
2659<p>Adds the elements of <code>b</code> to the corresponding elements of <code>a</code>.</p>
2660</dd>
2661<dt class="hdlist1">Returns: </dt>
2662<dd>
2663<p><code>a</code>.</p>
2664</dd>
2665</dl>
2666</div>
2667<hr>
2668</div>
2669<div class="sect3">
2670<h4 id="quat_plus"><code>operator+</code></h4>
2671<div class="listingblock">
2672<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2673<div class="content">
2674<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2675
2676  //Only enabled if:
2677  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value &amp;&amp;
2678  template &lt;class A,class B&gt;
2679  typename deduce_quat2&lt;A,B&gt;::type
2680  operator+( A const &amp; a, B const &amp; b );
2681
2682} }</code></pre>
2683</div>
2684</div>
2685<div class="dlist">
2686<dl>
2687<dt class="hdlist1">Returns: </dt>
2688<dd>
2689<p>A quaternion with elements equal to the elements of <code>a</code> added to the corresponding elements of <code>b</code>.</p>
2690</dd>
2691</dl>
2692</div>
2693<div class="admonitionblock note">
2694<table>
2695<tr>
2696<td class="icon">
2697<i class="fa icon-note" title="Note"></i>
2698</td>
2699<td class="content">
2700The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
2701</td>
2702</tr>
2703</table>
2704</div>
2705<hr>
2706</div>
2707<div class="sect3">
2708<h4 id="quat_div_eq_scalar"><code>operator/=</code> (scalar)</h4>
2709<div class="listingblock">
2710<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2711<div class="content">
2712<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2713
2714  //Only enabled if: is_quat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
2715  template &lt;class A,class B&gt;
2716  A &amp; operator/=( A &amp; a, B b );
2717
2718} }</code></pre>
2719</div>
2720</div>
2721<div class="dlist">
2722<dl>
2723<dt class="hdlist1">Effects: </dt>
2724<dd>
2725<p>This operation divides a quaternion by a scalar.</p>
2726</dd>
2727<dt class="hdlist1">Returns: </dt>
2728<dd>
2729<p><code>a</code>.</p>
2730</dd>
2731</dl>
2732</div>
2733<hr>
2734</div>
2735<div class="sect3">
2736<h4 id="quat_div_scalar"><code>operator/</code> (scalar)</h4>
2737<div class="listingblock">
2738<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2739<div class="content">
2740<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2741
2742  //Only enabled if: is_quat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
2743  template &lt;class A,class B&gt;
2744  typename deduce_quat&lt;A&gt;::type
2745  operator/( A const &amp; a, B b );
2746
2747} }</code></pre>
2748</div>
2749</div>
2750<div class="dlist">
2751<dl>
2752<dt class="hdlist1">Returns: </dt>
2753<dd>
2754<p>A quaternion that is the result of dividing the quaternion <code>a</code> by the scalar <code>b</code>.</p>
2755</dd>
2756</dl>
2757</div>
2758<div class="admonitionblock note">
2759<table>
2760<tr>
2761<td class="icon">
2762<i class="fa icon-note" title="Note"></i>
2763</td>
2764<td class="content">
2765The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
2766</td>
2767</tr>
2768</table>
2769</div>
2770<hr>
2771</div>
2772<div class="sect3">
2773<h4 id="quat_mul_eq_scalar"><code>operator*=</code> (scalar)</h4>
2774<div class="listingblock">
2775<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2776<div class="content">
2777<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2778
2779  //Only enabled if: is_quat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
2780  template &lt;class A,class B&gt;
2781  A &amp; operator*=( A &amp; a, B b );
2782
2783} }</code></pre>
2784</div>
2785</div>
2786<div class="dlist">
2787<dl>
2788<dt class="hdlist1">Effects: </dt>
2789<dd>
2790<p>This operation multiplies the quaternion <code>a</code> by the scalar <code>b</code>.</p>
2791</dd>
2792<dt class="hdlist1">Returns: </dt>
2793<dd>
2794<p><code>a</code>.</p>
2795</dd>
2796</dl>
2797</div>
2798<hr>
2799</div>
2800<div class="sect3">
2801<h4 id="quat_mul_eq"><code>operator*=</code></h4>
2802<div class="listingblock">
2803<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2804<div class="content">
2805<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2806
2807  //Only enabled if:
2808  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2809  template &lt;class A,class B&gt;
2810  A &amp; operator*=( A &amp; a, B const &amp; b );
2811
2812} }</code></pre>
2813</div>
2814</div>
2815<div class="dlist">
2816<dl>
2817<dt class="hdlist1">Effects: </dt>
2818<dd>
2819<p>As if:</p>
2820<div class="listingblock">
2821<div class="content">
2822<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">A tmp(a);
2823a = tmp * b;
2824return a;</code></pre>
2825</div>
2826</div>
2827</dd>
2828</dl>
2829</div>
2830<hr>
2831</div>
2832<div class="sect3">
2833<h4 id="quat_mul_scalar"><code>operator*</code> (scalar)</h4>
2834<div class="listingblock">
2835<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2836<div class="content">
2837<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2838
2839  //Only enabled if: is_quat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
2840  template &lt;class A,class B&gt;
2841  typename deduce_quat&lt;A&gt;::type
2842  operator*( A const &amp; a, B b );
2843
2844} }</code></pre>
2845</div>
2846</div>
2847<div class="dlist">
2848<dl>
2849<dt class="hdlist1">Returns: </dt>
2850<dd>
2851<p>A quaternion that is the result of multiplying the quaternion <code>a</code> by the scalar <code>b</code>.</p>
2852</dd>
2853</dl>
2854</div>
2855<div class="admonitionblock note">
2856<table>
2857<tr>
2858<td class="icon">
2859<i class="fa icon-note" title="Note"></i>
2860</td>
2861<td class="content">
2862The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
2863</td>
2864</tr>
2865</table>
2866</div>
2867<hr>
2868</div>
2869<div class="sect3">
2870<h4 id="quat_mul"><code>operator*</code></h4>
2871<div class="listingblock">
2872<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2873<div class="content">
2874<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2875
2876  //Only enabled if:
2877  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2878  template &lt;class A,class B&gt;
2879  typename deduce_quat2&lt;A,B&gt;::type
2880  operator*( A const &amp; a, B const &amp; b );
2881
2882} }</code></pre>
2883</div>
2884</div>
2885<div class="dlist">
2886<dl>
2887<dt class="hdlist1">Returns: </dt>
2888<dd>
2889<p>The result of multiplying the quaternions <code>a</code> and <code>b</code>.</p>
2890</dd>
2891</dl>
2892</div>
2893<div class="admonitionblock note">
2894<table>
2895<tr>
2896<td class="icon">
2897<i class="fa icon-note" title="Note"></i>
2898</td>
2899<td class="content">
2900The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
2901</td>
2902</tr>
2903</table>
2904</div>
2905<hr>
2906</div>
2907<div class="sect3">
2908<h4 id="quat_eq"><code>operator==</code></h4>
2909<div class="listingblock">
2910<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2911<div class="content">
2912<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2913
2914  //Only enabled if:
2915  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2916  template &lt;class A,class B&gt;
2917  bool operator==( A const &amp; a, B const &amp; b );
2918
2919} }</code></pre>
2920</div>
2921</div>
2922<div class="dlist">
2923<dl>
2924<dt class="hdlist1">Returns: </dt>
2925<dd>
2926<p><code>true</code> if each element of <code>a</code> compares equal to its corresponding element of <code>b</code>, <code>false</code> otherwise.</p>
2927</dd>
2928</dl>
2929</div>
2930<hr>
2931</div>
2932<div class="sect3">
2933<h4 id="quat_neq"><code>operator!=</code></h4>
2934<div class="listingblock">
2935<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2936<div class="content">
2937<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2938
2939  //Only enabled if:
2940  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2941  template &lt;class A,class B&gt;
2942  bool operator!=( A const &amp; a, B const &amp; b );
2943
2944} }</code></pre>
2945</div>
2946</div>
2947<div class="dlist">
2948<dl>
2949<dt class="hdlist1">Returns: </dt>
2950<dd>
2951<p><code>!(a == b)</code>.</p>
2952</dd>
2953</dl>
2954</div>
2955<hr>
2956</div>
2957<div class="sect3">
2958<h4 id="quat_cmp"><code>cmp</code></h4>
2959<div class="listingblock">
2960<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2961<div class="content">
2962<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2963
2964  //Only enabled if:
2965  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
2966  template &lt;class A,class B,class Cmp&gt;
2967  bool cmp( A const &amp; a, B const &amp; b, Cmp pred );
2968
2969} }</code></pre>
2970</div>
2971</div>
2972<div class="dlist">
2973<dl>
2974<dt class="hdlist1">Returns: </dt>
2975<dd>
2976<p>Similar to <a href="#quat_eq"><code>operator==</code></a>, except that it uses the binary predicate <code>pred</code> to compare the individual quaternion elements.</p>
2977</dd>
2978</dl>
2979</div>
2980<hr>
2981</div>
2982<div class="sect3">
2983<h4 id="quat_mag_sqr"><code>mag_sqr</code></h4>
2984<div class="listingblock">
2985<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
2986<div class="content">
2987<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
2988
2989  //Only enabled if: is_quat&lt;A&gt;::value
2990  template &lt;class A&gt;
2991  typename quat_traits&lt;A&gt;::scalar_type
2992  mag_sqr( A const &amp; a );
2993
2994} }</code></pre>
2995</div>
2996</div>
2997<div class="dlist">
2998<dl>
2999<dt class="hdlist1">Returns: </dt>
3000<dd>
3001<p>The squared magnitude of the quaternion <code>a</code>.</p>
3002</dd>
3003</dl>
3004</div>
3005<hr>
3006</div>
3007<div class="sect3">
3008<h4 id="quat_mag"><code>mag</code></h4>
3009<div class="listingblock">
3010<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3011<div class="content">
3012<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3013
3014  //Only enabled if: is_quat&lt;A&gt;::value
3015  template &lt;class A&gt;
3016  typename quat_traits&lt;A&gt;::scalar_type
3017  mag( A const &amp; a );
3018
3019} }</code></pre>
3020</div>
3021</div>
3022<div class="dlist">
3023<dl>
3024<dt class="hdlist1">Returns: </dt>
3025<dd>
3026<p>The magnitude of the quaternion <code>a</code>.</p>
3027</dd>
3028</dl>
3029</div>
3030<hr>
3031</div>
3032<div class="sect3">
3033<h4 id="quat_normalized"><code>normalized</code></h4>
3034<div class="listingblock">
3035<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3036<div class="content">
3037<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3038
3039  //Only enabled if: is_quat&lt;A&gt;::value
3040  template &lt;class A&gt;
3041  typename deduce_quat&lt;A&gt;::type
3042  normalized( A const &amp; a );
3043
3044} }</code></pre>
3045</div>
3046</div>
3047<div class="dlist">
3048<dl>
3049<dt class="hdlist1">Effects: </dt>
3050<dd>
3051<p>As if:</p>
3052<div class="listingblock">
3053<div class="content">
3054<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">typename deduce_quat&lt;A&gt;::type tmp;
3055assign(tmp,a);
3056normalize(tmp);
3057return tmp;</code></pre>
3058</div>
3059</div>
3060</dd>
3061</dl>
3062</div>
3063<div class="admonitionblock note">
3064<table>
3065<tr>
3066<td class="icon">
3067<i class="fa icon-note" title="Note"></i>
3068</td>
3069<td class="content">
3070The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
3071</td>
3072</tr>
3073</table>
3074</div>
3075<hr>
3076</div>
3077<div class="sect3">
3078<h4 id="quat_normalize"><code>normalize</code></h4>
3079<div class="listingblock">
3080<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3081<div class="content">
3082<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3083
3084  //Only enabled if: is_quat&lt;A&gt;::value
3085  template &lt;class A&gt;
3086  void normalize( A &amp; a );
3087
3088} }</code></pre>
3089</div>
3090</div>
3091<div class="dlist">
3092<dl>
3093<dt class="hdlist1">Effects: </dt>
3094<dd>
3095<p>Normalizes <code>a</code>.</p>
3096</dd>
3097<dt class="hdlist1">Ensures: </dt>
3098<dd>
3099<p><code>mag(a)==scalar_traits&lt;typename quat_traits&lt;A&gt;::scalar_type&gt;::value(1).</code></p>
3100</dd>
3101<dt class="hdlist1">Throws: </dt>
3102<dd>
3103<p>If the magnitude of <code>a</code> is zero, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
3104</dd>
3105</dl>
3106</div>
3107<hr>
3108</div>
3109<div class="sect3">
3110<h4 id="quat_dot"><code>dot</code></h4>
3111<div class="listingblock">
3112<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3113<div class="content">
3114<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3115
3116  //Only enabled if:
3117  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value
3118  template &lt;class A,class B&gt;
3119  typename deduce_scalar&lt;A,B&gt;::type
3120  dot( A const &amp; a, B const &amp; b );
3121
3122} }</code></pre>
3123</div>
3124</div>
3125<div class="dlist">
3126<dl>
3127<dt class="hdlist1">Returns: </dt>
3128<dd>
3129<p>The dot product of the quaternions <code>a</code> and <code>b</code>.</p>
3130</dd>
3131</dl>
3132</div>
3133<div class="admonitionblock note">
3134<table>
3135<tr>
3136<td class="icon">
3137<i class="fa icon-note" title="Note"></i>
3138</td>
3139<td class="content">
3140The <a href="#deduce_scalar"><code>deduce_scalar</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
3141</td>
3142</tr>
3143</table>
3144</div>
3145<hr>
3146</div>
3147<div class="sect3">
3148<h4 id="conjugate"><code>conjugate</code></h4>
3149<div class="listingblock">
3150<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3151<div class="content">
3152<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3153
3154  //Only enabled if: is_quat&lt;A&gt;::value
3155  template &lt;class A&gt;
3156  typename deduce_quat&lt;A&gt;::type
3157  conjugate( A const &amp; a );
3158
3159} }</code></pre>
3160</div>
3161</div>
3162<div class="dlist">
3163<dl>
3164<dt class="hdlist1">Returns: </dt>
3165<dd>
3166<p>Computes the conjugate of <code>a</code>.</p>
3167</dd>
3168</dl>
3169</div>
3170<div class="admonitionblock note">
3171<table>
3172<tr>
3173<td class="icon">
3174<i class="fa icon-note" title="Note"></i>
3175</td>
3176<td class="content">
3177The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
3178</td>
3179</tr>
3180</table>
3181</div>
3182<hr>
3183</div>
3184<div class="sect3">
3185<h4 id="quat_inverse"><code>inverse</code></h4>
3186<div class="listingblock">
3187<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3188<div class="content">
3189<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3190
3191  //Only enabled if: is_quat&lt;A&gt;::value
3192  template &lt;class A&gt;
3193  typename deduce_quat&lt;A&gt;::type
3194  inverse( A const &amp; a );
3195
3196} }</code></pre>
3197</div>
3198</div>
3199<div class="dlist">
3200<dl>
3201<dt class="hdlist1">Returns: </dt>
3202<dd>
3203<p>Computes the multiplicative inverse of <code>a</code>, or the conjugate-to-norm ratio.</p>
3204</dd>
3205<dt class="hdlist1">Throws: </dt>
3206<dd>
3207<p>If the magnitude of <code>a</code> is zero, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
3208</dd>
3209</dl>
3210</div>
3211<div class="admonitionblock tip">
3212<table>
3213<tr>
3214<td class="icon">
3215<i class="fa icon-tip" title="Tip"></i>
3216</td>
3217<td class="content">
3218If <code>a</code> is known to be unit length, <code>conjugate</code> is equivalent to <a href="#quat_inverse"><code>inverse</code></a>, yet it is faster to compute.
3219</td>
3220</tr>
3221</table>
3222</div>
3223<div class="admonitionblock note">
3224<table>
3225<tr>
3226<td class="icon">
3227<i class="fa icon-note" title="Note"></i>
3228</td>
3229<td class="content">
3230The <a href="#deduce_quat"><code>deduce_quat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
3231</td>
3232</tr>
3233</table>
3234</div>
3235<hr>
3236</div>
3237<div class="sect3">
3238<h4 id="slerp"><code>slerp</code></h4>
3239<div class="listingblock">
3240<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3241<div class="content">
3242<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3243
3244  //Only enabled if:
3245  //  is_quat&lt;A&gt;::value &amp;&amp; is_quat&lt;B&gt;::value &amp;&amp; is_scalar&lt;C&gt;
3246  template &lt;class A,class B,class C&gt;
3247  typename deduce_quat2&lt;A,B&gt; &gt;::type
3248  slerp( A const &amp; a, B const &amp; b, C c );
3249
3250} }</code></pre>
3251</div>
3252</div>
3253<div class="dlist">
3254<dl>
3255<dt class="hdlist1">Preconditions: </dt>
3256<dd>
3257<p><code>t&gt;=0 &amp;&amp; t&lt;=1</code>.</p>
3258</dd>
3259<dt class="hdlist1">Returns: </dt>
3260<dd>
3261<p>A quaternion that is the result of Spherical Linear Interpolation of the quaternions <code>a</code> and <code>b</code> and the interpolation parameter <code>c</code>. When <code>slerp</code> is applied to unit quaternions, the quaternion path maps to a path through 3D rotations in a standard way. The effect is a rotation with uniform angular velocity around a fixed rotation axis.</p>
3262</dd>
3263</dl>
3264</div>
3265<div class="admonitionblock note">
3266<table>
3267<tr>
3268<td class="icon">
3269<i class="fa icon-note" title="Note"></i>
3270</td>
3271<td class="content">
3272The <a href="#deduce_quat2"><code>deduce_quat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
3273</td>
3274</tr>
3275</table>
3276</div>
3277<hr>
3278</div>
3279<div class="sect3">
3280<h4 id="zero_quat"><code>zero_quat</code></h4>
3281<div class="listingblock">
3282<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3283<div class="content">
3284<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3285
3286  template &lt;class T&gt;
3287  -unspecified-return-type- zero_quat();
3288
3289} }</code></pre>
3290</div>
3291</div>
3292<div class="dlist">
3293<dl>
3294<dt class="hdlist1">Returns: </dt>
3295<dd>
3296<p>A read-only quaternion of unspecified type with <a href="#scalar_traits"><code>scalar_type</code></a> <code>T</code>, with all elements equal to <a href="#scalar_traits"><code>scalar_traits&lt;T&gt;::value(0)</code></a>.</p>
3297</dd>
3298</dl>
3299</div>
3300<hr>
3301</div>
3302<div class="sect3">
3303<h4 id="quat_set_zero"><code>set_zero</code></h4>
3304<div class="listingblock">
3305<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3306<div class="content">
3307<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3308
3309  //Only enabled if: is_quat&lt;A&gt;::value
3310  template &lt;class A&gt;
3311  void set_zero( A &amp; a );
3312
3313} }</code></pre>
3314</div>
3315</div>
3316<div class="dlist">
3317<dl>
3318<dt class="hdlist1">Effects: </dt>
3319<dd>
3320<p>As if:</p>
3321<div class="listingblock">
3322<div class="content">
3323<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(a,
3324  zero_quat&lt;typename quat_traits&lt;A&gt;::scalar_type&gt;());</code></pre>
3325</div>
3326</div>
3327</dd>
3328</dl>
3329</div>
3330<hr>
3331</div>
3332<div class="sect3">
3333<h4 id="identity_quat"><code>identity_quat</code></h4>
3334<div class="listingblock">
3335<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3336<div class="content">
3337<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3338
3339  template &lt;class S&gt;
3340  -unspecified-return-type- identity_quat();
3341
3342} }</code></pre>
3343</div>
3344</div>
3345<div class="dlist">
3346<dl>
3347<dt class="hdlist1">Returns: </dt>
3348<dd>
3349<p>An identity quaternion with scalar type <code>S</code>.</p>
3350</dd>
3351</dl>
3352</div>
3353<hr>
3354</div>
3355<div class="sect3">
3356<h4 id="quat_set_identity"><code>set_identity</code></h4>
3357<div class="listingblock">
3358<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3359<div class="content">
3360<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3361
3362  //Only enabled if: is_quat&lt;A&gt;::value
3363  template &lt;class A&gt;
3364  void set_identity( A &amp; a );
3365
3366} }</code></pre>
3367</div>
3368</div>
3369<div class="dlist">
3370<dl>
3371<dt class="hdlist1">Effects: </dt>
3372<dd>
3373<p>As if:</p>
3374<div class="listingblock">
3375<div class="content">
3376<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
3377  a,
3378  identity_quat&lt;typename quat_traits&lt;A&gt;::scalar_type&gt;());</code></pre>
3379</div>
3380</div>
3381</dd>
3382</dl>
3383</div>
3384<hr>
3385</div>
3386<div class="sect3">
3387<h4 id="rot_quat"><code>rot_quat</code></h4>
3388<div class="listingblock">
3389<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3390<div class="content">
3391<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3392
3393  //Only enabled if:
3394  //  is_vec&lt;A&gt;::value &amp;&amp; vec_traits&lt;A&gt;::dim==3
3395  template &lt;class A&gt;
3396  -unspecified-return-type- rot_quat( A const &amp; axis, typename vec_traits&lt;A&gt;::scalar_type angle );
3397
3398} }</code></pre>
3399</div>
3400</div>
3401<div class="dlist">
3402<dl>
3403<dt class="hdlist1">Returns: </dt>
3404<dd>
3405<p>A quaternion of unspecified type which performs a rotation around the <code>axis</code> at <code>angle</code> radians.</p>
3406</dd>
3407<dt class="hdlist1">Throws: </dt>
3408<dd>
3409<p>In case the axis vector has zero magnitude, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
3410</dd>
3411</dl>
3412</div>
3413<div class="admonitionblock note">
3414<table>
3415<tr>
3416<td class="icon">
3417<i class="fa icon-note" title="Note"></i>
3418</td>
3419<td class="content">
3420The <code>rot_quat</code> function is not a <a href="#view_proxy">view proxy</a>; it returns a temp object.
3421</td>
3422</tr>
3423</table>
3424</div>
3425<hr>
3426</div>
3427<div class="sect3">
3428<h4 id="quat_set_rot"><code>set_rot</code></h4>
3429<div class="listingblock">
3430<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3431<div class="content">
3432<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3433
3434  //Only enabled if:
3435  //  is_quat&lt;A&gt;::value &amp;&amp;
3436  //  is_vec&lt;B&gt;::value &amp;&amp; vec_traits&lt;B&gt;::dim==3
3437  template &lt;class A&gt;
3438  void set_rot( A &amp; a, B const &amp; axis, typename vec_traits&lt;B&gt;::scalar_type angle );
3439
3440} }</code></pre>
3441</div>
3442</div>
3443<div class="dlist">
3444<dl>
3445<dt class="hdlist1">Effects: </dt>
3446<dd>
3447<p>As if:</p>
3448<div class="listingblock">
3449<div class="content">
3450<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
3451  a,
3452  rot_quat(axis,angle));</code></pre>
3453</div>
3454</div>
3455</dd>
3456</dl>
3457</div>
3458<hr>
3459</div>
3460<div class="sect3">
3461<h4 id="quat_rotate"><code>rotate</code></h4>
3462<div class="listingblock">
3463<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3464<div class="content">
3465<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3466
3467  //Only enabled if:
3468  //  is_quat&lt;A&gt;::value &amp;&amp;
3469  //  is_vec&lt;B&gt;::value &amp;&amp; vec_traits&lt;B&gt;::dim==3
3470  template &lt;class A,class B&gt;
3471  void rotate( A &amp; a, B const &amp; axis, typename quat_traits&lt;A&gt;::scalar_type angle );
3472
3473} }</code></pre>
3474</div>
3475</div>
3476<div class="dlist">
3477<dl>
3478<dt class="hdlist1">Effects: </dt>
3479<dd>
3480<p>As if: <code>a *= <a href="#rot_quat">rot_quat</a>(axis,angle)</code>.</p>
3481</dd>
3482</dl>
3483</div>
3484<hr>
3485</div>
3486<div class="sect3">
3487<h4 id="rotx_quat"><code>rotx_quat</code></h4>
3488<div class="listingblock">
3489<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3490<div class="content">
3491<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3492
3493  template &lt;class Angle&gt;
3494  -unspecified-return-type- rotx_quat( Angle const &amp; angle );
3495
3496} }</code></pre>
3497</div>
3498</div>
3499<div class="dlist">
3500<dl>
3501<dt class="hdlist1">Returns: </dt>
3502<dd>
3503<p>A <a href="#view_proxy">view proxy</a> quaternion of unspecified type and scalar type <code>Angle</code>, which performs a rotation around the X axis at <code>angle</code> radians.</p>
3504</dd>
3505</dl>
3506</div>
3507<hr>
3508</div>
3509<div class="sect3">
3510<h4 id="quat_set_rotx"><code>set_rotx</code></h4>
3511<div class="listingblock">
3512<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3513<div class="content">
3514<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3515
3516  //Only enabled if: is_quat&lt;A&gt;::value
3517  template &lt;class A&gt;
3518  void set_rotx( A &amp; a, typename quat_traits&lt;A&gt;::scalar_type angle );
3519
3520} }</code></pre>
3521</div>
3522</div>
3523<div class="dlist">
3524<dl>
3525<dt class="hdlist1">Effects: </dt>
3526<dd>
3527<p>As if:</p>
3528<div class="listingblock">
3529<div class="content">
3530<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
3531  a,
3532  rotx_quat(angle));</code></pre>
3533</div>
3534</div>
3535</dd>
3536</dl>
3537</div>
3538<hr>
3539</div>
3540<div class="sect3">
3541<h4 id="quat_rotate_x"><code>rotate_x</code></h4>
3542<div class="listingblock">
3543<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3544<div class="content">
3545<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3546
3547  //Only enabled if: is_quat&lt;A&gt;::value
3548  template &lt;class A&gt;
3549  void rotate_x( A &amp; a, typename quat_traits&lt;A&gt;::scalar_type angle );
3550
3551} }</code></pre>
3552</div>
3553</div>
3554<div class="dlist">
3555<dl>
3556<dt class="hdlist1">Effects: </dt>
3557<dd>
3558<p>As if: <code>a *= <a href="#rotx_quat">rotx_quat</a>(angle)</code>.</p>
3559</dd>
3560</dl>
3561</div>
3562<hr>
3563</div>
3564<div class="sect3">
3565<h4 id="roty_quat"><code>roty_quat</code></h4>
3566<div class="listingblock">
3567<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3568<div class="content">
3569<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3570
3571  template &lt;class Angle&gt;
3572  -unspecified-return-type- roty_quat( Angle const &amp; angle );
3573
3574} }</code></pre>
3575</div>
3576</div>
3577<div class="dlist">
3578<dl>
3579<dt class="hdlist1">Returns: </dt>
3580<dd>
3581<p>A <a href="#view_proxy">view proxy</a> quaternion of unspecified type and scalar type <code>Angle</code>, which performs a rotation around the Y axis at <code>angle</code> radians.</p>
3582</dd>
3583</dl>
3584</div>
3585<hr>
3586</div>
3587<div class="sect3">
3588<h4 id="quat_set_roty"><code>set_roty</code></h4>
3589<div class="listingblock">
3590<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3591<div class="content">
3592<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3593
3594  //Only enabled if: is_quat&lt;A&gt;::value
3595  template &lt;class A&gt;
3596  void set_rotz( A &amp; a, typename quat_traits&lt;A&gt;::scalar_type angle );
3597
3598} }</code></pre>
3599</div>
3600</div>
3601<div class="dlist">
3602<dl>
3603<dt class="hdlist1">Effects: </dt>
3604<dd>
3605<p>As if:</p>
3606<div class="listingblock">
3607<div class="content">
3608<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
3609  a,
3610  roty_quat(angle));</code></pre>
3611</div>
3612</div>
3613</dd>
3614</dl>
3615</div>
3616<hr>
3617</div>
3618<div class="sect3">
3619<h4 id="quat_rotate_y"><code>rotate_y</code></h4>
3620<div class="listingblock">
3621<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3622<div class="content">
3623<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3624
3625  //Only enabled if: is_quat&lt;A&gt;::value
3626  template &lt;class A&gt;
3627  void rotate_y( A &amp; a, typename quat_traits&lt;A&gt;::scalar_type angle );
3628
3629} }</code></pre>
3630</div>
3631</div>
3632<div class="dlist">
3633<dl>
3634<dt class="hdlist1">Effects: </dt>
3635<dd>
3636<p>As if: <code>a *= <a href="#roty_quat">roty_quat</a>(angle)</code>.</p>
3637</dd>
3638</dl>
3639</div>
3640<hr>
3641</div>
3642<div class="sect3">
3643<h4 id="rotz_quat"><code>rotz_quat</code></h4>
3644<div class="listingblock">
3645<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3646<div class="content">
3647<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3648
3649    template &lt;class Angle&gt;
3650    -unspecified-return-type- rotz_quat( Angle const &amp; angle );
3651
3652} }</code></pre>
3653</div>
3654</div>
3655<div class="dlist">
3656<dl>
3657<dt class="hdlist1">Returns: </dt>
3658<dd>
3659<p>A <a href="#view_proxy">view proxy</a> quaternion of unspecified type and scalar type <code>Angle</code>, which performs a rotation around the Z axis at <code>angle</code> radians.</p>
3660</dd>
3661</dl>
3662</div>
3663<hr>
3664</div>
3665<div class="sect3">
3666<h4 id="quat_set_rotz"><code>set_rotz</code></h4>
3667<div class="listingblock">
3668<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3669<div class="content">
3670<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3671
3672  //Only enabled if: is_quat&lt;A&gt;::value
3673  template &lt;class A&gt;
3674  void set_rotz( A &amp; a, typename quat_traits&lt;A&gt;::scalar_type angle );
3675
3676} }</code></pre>
3677</div>
3678</div>
3679<div class="dlist">
3680<dl>
3681<dt class="hdlist1">Effects: </dt>
3682<dd>
3683<p>As if:</p>
3684<div class="listingblock">
3685<div class="content">
3686<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
3687  a,
3688  rotz_quat(angle));</code></pre>
3689</div>
3690</div>
3691</dd>
3692</dl>
3693</div>
3694<hr>
3695</div>
3696<div class="sect3">
3697<h4 id="quat_rotate_z"><code>rotate_z</code></h4>
3698<div class="listingblock">
3699<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3700<div class="content">
3701<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3702
3703  //Only enabled if: is_quat&lt;A&gt;::value
3704  template &lt;class A&gt;
3705  void rotate_z( A &amp; a, typename quat_traits&lt;A&gt;::scalar_type angle );
3706
3707} }</code></pre>
3708</div>
3709</div>
3710<div class="dlist">
3711<dl>
3712<dt class="hdlist1">Effects: </dt>
3713<dd>
3714<p>As if: <code>a *= <a href="#rotz_quat">rotz_quat</a>(angle)</code>.</p>
3715</dd>
3716</dl>
3717</div>
3718<hr>
3719</div>
3720<div class="sect3">
3721<h4 id="quat_scalar_cast"><code>scalar_cast</code></h4>
3722<div class="listingblock">
3723<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3724<div class="content">
3725<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3726
3727  //Only enabled if: is_quat&lt;A&gt;::value
3728  template &lt;class Scalar,class A&gt;
3729  -unspecified-return_type- scalar_cast( A const &amp; a );
3730
3731} }</code></pre>
3732</div>
3733</div>
3734<div class="dlist">
3735<dl>
3736<dt class="hdlist1">Returns: </dt>
3737<dd>
3738<p>A read-only <a href="#view_proxy">view proxy</a> of <code>a</code> that looks like a quaternion of the same dimensions as <code>a</code>, but with <a href="#quat_traits"><code>scalar_type</code></a> <code>Scalar</code> and elements constructed from the corresponding elements of <code>a</code>.</p>
3739</dd>
3740</dl>
3741</div>
3742<hr>
3743</div>
3744<div class="sect3">
3745<h4 id="qref"><code>qref</code></h4>
3746<div class="listingblock">
3747<div class="title">#include &lt;boost/qvm/quat_operations.hpp&gt;</div>
3748<div class="content">
3749<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3750
3751  //Only enabled if: is_quat&lt;A&gt;::value
3752  template &lt;class A&gt;
3753  -unspecified-return-type- qref( A &amp; a );
3754
3755} }</code></pre>
3756</div>
3757</div>
3758<div class="dlist">
3759<dl>
3760<dt class="hdlist1">Returns: </dt>
3761<dd>
3762<p>An identity view proxy of <code>a</code>; that is, it simply accesses the elements of <code>a</code>.</p>
3763</dd>
3764</dl>
3765</div>
3766<div class="admonitionblock tip">
3767<table>
3768<tr>
3769<td class="icon">
3770<i class="fa icon-tip" title="Tip"></i>
3771</td>
3772<td class="content">
3773<code>qref</code> allows calling QVM operations when <code>a</code> is of built-in type, for example a plain old C array.
3774</td>
3775</tr>
3776</table>
3777</div>
3778<hr>
3779</div>
3780</div>
3781<div class="sect2">
3782<h3 id="_vector_operations">Vector Operations</h3>
3783<div class="sect3">
3784<h4 id="vec_assign"><code>assign</code></h4>
3785<div class="listingblock">
3786<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3787<div class="content">
3788<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3789
3790    //Only enabled if:
3791    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
3792    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
3793    template &lt;class A,class B&gt;
3794    A &amp; assign( A &amp; a, B const &amp; b );
3795
3796} }</code></pre>
3797</div>
3798</div>
3799<div class="dlist">
3800<dl>
3801<dt class="hdlist1">Effects: </dt>
3802<dd>
3803<p>Copies all elements of the vector <code>b</code> to the vector <code>a</code>.</p>
3804</dd>
3805<dt class="hdlist1">Returns: </dt>
3806<dd>
3807<p><code>a</code>.</p>
3808</dd>
3809</dl>
3810</div>
3811<hr>
3812</div>
3813<div class="sect3">
3814<h4 id="vec_convert_to"><code>convert_to</code></h4>
3815<div class="listingblock">
3816<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3817<div class="content">
3818<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3819
3820    //Only enabled if:
3821    //  is_vec&lt;R&gt;::value &amp;&amp; is_vec&lt;A&gt;::value &amp;&amp;
3822    //  vec_traits&lt;R&gt;::dim==vec_traits&lt;A&gt;::dim
3823    template &lt;class R,class A&gt;
3824    R convert_to( A const &amp; a );
3825
3826} }</code></pre>
3827</div>
3828</div>
3829<div class="dlist">
3830<dl>
3831<dt class="hdlist1">Requires: </dt>
3832<dd>
3833<p><code>R</code> must be copyable.</p>
3834</dd>
3835<dt class="hdlist1">Effects: </dt>
3836<dd>
3837<p>As if: <code>R r; assign(r,a); return r;</code></p>
3838</dd>
3839</dl>
3840</div>
3841<hr>
3842</div>
3843<div class="sect3">
3844<h4 id="vec_minus_eq"><code>operator-=</code></h4>
3845<div class="listingblock">
3846<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3847<div class="content">
3848<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3849
3850    //Only enabled if:
3851    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
3852    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
3853    template &lt;class A,class B&gt;
3854    A &amp; operator-=( A &amp; a, B const &amp; b );
3855
3856} }</code></pre>
3857</div>
3858</div>
3859<div class="dlist">
3860<dl>
3861<dt class="hdlist1">Effects: </dt>
3862<dd>
3863<p>Subtracts the elements of <code>b</code> from the corresponding elements of <code>a</code>.</p>
3864</dd>
3865<dt class="hdlist1">Returns: </dt>
3866<dd>
3867<p><code>a</code>.</p>
3868</dd>
3869</dl>
3870</div>
3871<hr>
3872</div>
3873<div class="sect3">
3874<h4 id="vec_minus_unary"><code>operator-</code> (unary)</h4>
3875<div class="paragraph">
3876<p>operator-(vec)</p>
3877</div>
3878<div class="listingblock">
3879<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3880<div class="content">
3881<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3882
3883    //Only enabled if: is_vec&lt;A&gt;::value
3884    template &lt;class A&gt;
3885    typename deduce_vec&lt;A&gt;::type
3886    operator-( A const &amp; a );
3887
3888} }</code></pre>
3889</div>
3890</div>
3891<div class="dlist">
3892<dl>
3893<dt class="hdlist1">Returns: </dt>
3894<dd>
3895<p>A vector of the negated elements of <code>a</code>.</p>
3896</dd>
3897</dl>
3898</div>
3899<div class="admonitionblock note">
3900<table>
3901<tr>
3902<td class="icon">
3903<i class="fa icon-note" title="Note"></i>
3904</td>
3905<td class="content">
3906The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
3907</td>
3908</tr>
3909</table>
3910</div>
3911<hr>
3912</div>
3913<div class="sect3">
3914<h4 id="vec_minus"><code>operator-</code> (binary)</h4>
3915<div class="listingblock">
3916<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3917<div class="content">
3918<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3919
3920    //Only enabled if:
3921    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
3922    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
3923    template &lt;class A,class B&gt;
3924    typename deduce_vec2&lt;A,B,vec_traits&lt;A&gt;::dim&gt;::type
3925    operator-( A const &amp; a, B const &amp; b );
3926
3927} }</code></pre>
3928</div>
3929</div>
3930<div class="dlist">
3931<dl>
3932<dt class="hdlist1">Returns: </dt>
3933<dd>
3934<p>A vector of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> subtracted from the corresponding elements of <code>a</code>.</p>
3935</dd>
3936</dl>
3937</div>
3938<div class="admonitionblock note">
3939<table>
3940<tr>
3941<td class="icon">
3942<i class="fa icon-note" title="Note"></i>
3943</td>
3944<td class="content">
3945The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
3946</td>
3947</tr>
3948</table>
3949</div>
3950<hr>
3951</div>
3952<div class="sect3">
3953<h4 id="vec_plus_eq"><code>operator+=</code></h4>
3954<div class="listingblock">
3955<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3956<div class="content">
3957<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3958
3959    //Only enabled if:
3960    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
3961    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
3962    template &lt;class A,class B&gt;
3963    A &amp; operator+=( A &amp; a, B const &amp; b );
3964
3965} }</code></pre>
3966</div>
3967</div>
3968<div class="dlist">
3969<dl>
3970<dt class="hdlist1">Effects: </dt>
3971<dd>
3972<p>Adds the elements of <code>b</code> to the corresponding elements of <code>a</code>.</p>
3973</dd>
3974<dt class="hdlist1">Returns: </dt>
3975<dd>
3976<p><code>a</code>.</p>
3977</dd>
3978</dl>
3979</div>
3980<hr>
3981</div>
3982<div class="sect3">
3983<h4 id="vec_plus"><code>operator+</code></h4>
3984<div class="listingblock">
3985<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
3986<div class="content">
3987<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
3988
3989    //Only enabled if:
3990    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
3991    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
3992    template &lt;class A,class B&gt;
3993    typename deduce_vec2&lt;A,B,vec_traits&lt;A&gt;::dim&gt;::type
3994    operator+( A const &amp; a, B const &amp; b );
3995
3996} }</code></pre>
3997</div>
3998</div>
3999<div class="dlist">
4000<dl>
4001<dt class="hdlist1">Returns: </dt>
4002<dd>
4003<p>A vector of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> added to the corresponding elements of <code>a</code>.</p>
4004</dd>
4005</dl>
4006</div>
4007<div class="admonitionblock note">
4008<table>
4009<tr>
4010<td class="icon">
4011<i class="fa icon-note" title="Note"></i>
4012</td>
4013<td class="content">
4014The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
4015</td>
4016</tr>
4017</table>
4018</div>
4019<hr>
4020</div>
4021<div class="sect3">
4022<h4 id="vec_div_eq_scalar"><code>operator/=</code> (scalar)</h4>
4023<div class="listingblock">
4024<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4025<div class="content">
4026<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4027
4028    //Only enabled if: is_vec&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4029    template &lt;class A,class B&gt;
4030    A &amp; operator/=( A &amp; a, B b );
4031
4032} }</code></pre>
4033</div>
4034</div>
4035<div class="dlist">
4036<dl>
4037<dt class="hdlist1">Effects: </dt>
4038<dd>
4039<p>This operation divides a vector by a scalar.</p>
4040</dd>
4041<dt class="hdlist1">Returns: </dt>
4042<dd>
4043<p><code>a</code>.</p>
4044</dd>
4045</dl>
4046</div>
4047<hr>
4048</div>
4049<div class="sect3">
4050<h4 id="vec_div_scalar"><code>operator/</code></h4>
4051<div class="listingblock">
4052<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4053<div class="content">
4054<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4055
4056    //Only enabled if: is_vec&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4057    template &lt;class A,class B&gt;
4058    typename deduce_vec&lt;A&gt;::type
4059    operator/( A const &amp; a, B b );
4060
4061} }</code></pre>
4062</div>
4063</div>
4064<div class="dlist">
4065<dl>
4066<dt class="hdlist1">Returns: </dt>
4067<dd>
4068<p>A vector that is the result of dividing the vector <code>a</code> by the scalar <code>b</code>.</p>
4069</dd>
4070</dl>
4071</div>
4072<div class="admonitionblock note">
4073<table>
4074<tr>
4075<td class="icon">
4076<i class="fa icon-note" title="Note"></i>
4077</td>
4078<td class="content">
4079The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
4080</td>
4081</tr>
4082</table>
4083</div>
4084<hr>
4085</div>
4086<div class="sect3">
4087<h4 id="vec_mul_eq_scalar"><code>operator*=</code></h4>
4088<div class="listingblock">
4089<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4090<div class="content">
4091<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4092
4093    //Only enabled if: is_vec&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4094    template &lt;class A,class B&gt;
4095    A &amp; operator*=( A &amp; a, B b );
4096
4097} }</code></pre>
4098</div>
4099</div>
4100<div class="dlist">
4101<dl>
4102<dt class="hdlist1">Effects: </dt>
4103<dd>
4104<p>This operation multiplies the vector <code>a</code> by the scalar <code>b</code>.</p>
4105</dd>
4106<dt class="hdlist1">Returns: </dt>
4107<dd>
4108<p><code>a</code>.</p>
4109</dd>
4110</dl>
4111</div>
4112<hr>
4113</div>
4114<div class="sect3">
4115<h4 id="vec_mul_scalar"><code>operator*</code></h4>
4116<div class="listingblock">
4117<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4118<div class="content">
4119<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4120
4121    //Only enabled if: is_vec&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4122    template &lt;class A&gt;
4123    typename deduce_vec&lt;A&gt;::type
4124    operator*( A const &amp; a, B b );
4125
4126} }</code></pre>
4127</div>
4128</div>
4129<div class="dlist">
4130<dl>
4131<dt class="hdlist1">Returns: </dt>
4132<dd>
4133<p>A vector that is the result of multiplying the vector <code>a</code> by the scalar <code>b</code>.</p>
4134</dd>
4135</dl>
4136</div>
4137<div class="admonitionblock note">
4138<table>
4139<tr>
4140<td class="icon">
4141<i class="fa icon-note" title="Note"></i>
4142</td>
4143<td class="content">
4144The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
4145</td>
4146</tr>
4147</table>
4148</div>
4149<hr>
4150</div>
4151<div class="sect3">
4152<h4 id="vec_eq"><code>operator==</code></h4>
4153<div class="listingblock">
4154<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4155<div class="content">
4156<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4157
4158    //Only enabled if:
4159    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
4160    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
4161    template &lt;class A,class B&gt;
4162    bool operator==( A const &amp; a, B const &amp; b );
4163
4164} }</code></pre>
4165</div>
4166</div>
4167<div class="dlist">
4168<dl>
4169<dt class="hdlist1">Returns: </dt>
4170<dd>
4171<p><code>true</code> if each element of <code>a</code> compares equal to its corresponding element of <code>b</code>, <code>false</code> otherwise.</p>
4172</dd>
4173</dl>
4174</div>
4175<hr>
4176</div>
4177<div class="sect3">
4178<h4 id="vec_neq"><code>operator!=</code></h4>
4179<div class="listingblock">
4180<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4181<div class="content">
4182<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4183
4184    //Only enabled if:
4185    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
4186    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
4187    template &lt;class A,class B&gt;
4188    bool operator!=( A const &amp; a, B const &amp; b );
4189
4190} }</code></pre>
4191</div>
4192</div>
4193<div class="dlist">
4194<dl>
4195<dt class="hdlist1">Returns: </dt>
4196<dd>
4197<p><code>!(a == b)</code>.</p>
4198</dd>
4199</dl>
4200</div>
4201<hr>
4202</div>
4203<div class="sect3">
4204<h4 id="vec_cmp"><code>cmp</code></h4>
4205<div class="listingblock">
4206<div class="content">
4207<pre class="nowrap">.#include &lt;boost/qvm/mat_operations.hpp&gt;
4208
4209namespace boost
4210{
4211  namespace qvm
4212  {
4213    //Only enabled if:
4214    //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4215    //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4216    //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4217    template &lt;class A,class B,class Cmp&gt;
4218    bool cmp( A const &amp; a, B const &amp; b, Cmp pred );
4219
4220} }</pre>
4221</div>
4222</div>
4223<div class="dlist">
4224<dl>
4225<dt class="hdlist1">Returns: </dt>
4226<dd>
4227<p>Similar to <a href="#vec_eq"><code>operator==</code></a>, except that the individual elements of <code>a</code> and <code>b</code> are passed to the binary predicate <code>pred</code> for comparison.</p>
4228</dd>
4229</dl>
4230</div>
4231<hr>
4232</div>
4233<div class="sect3">
4234<h4 id="vec_mag_sqr"><code>mag_sqr</code></h4>
4235<div class="listingblock">
4236<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4237<div class="content">
4238<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4239
4240    //Only enabled if:
4241    //  is_vec&lt;A&gt;::value
4242    template &lt;class A&gt;
4243    typename vec_traits&lt;A&gt;::scalar_type
4244    mag_sqr( A const &amp; a );
4245
4246} }</code></pre>
4247</div>
4248</div>
4249<div class="dlist">
4250<dl>
4251<dt class="hdlist1">Returns: </dt>
4252<dd>
4253<p>The squared magnitude of the vector <code>a</code>.</p>
4254</dd>
4255</dl>
4256</div>
4257<hr>
4258</div>
4259<div class="sect3">
4260<h4 id="vec_mag"><code>mag</code></h4>
4261<div class="listingblock">
4262<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4263<div class="content">
4264<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4265
4266    //Only enabled if:
4267    //  is_vec&lt;A&gt;::value
4268    template &lt;class A&gt;
4269    typename vec_traits&lt;A&gt;::scalar_type
4270    mag( A const &amp; a );
4271
4272} }</code></pre>
4273</div>
4274</div>
4275<div class="dlist">
4276<dl>
4277<dt class="hdlist1">Returns: </dt>
4278<dd>
4279<p>The magnitude of the vector <code>a</code>.</p>
4280</dd>
4281</dl>
4282</div>
4283<hr>
4284</div>
4285<div class="sect3">
4286<h4 id="vec_normalized"><code>normalized</code></h4>
4287<div class="listingblock">
4288<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4289<div class="content">
4290<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4291
4292    //Only enabled if:
4293    //  is_vec&lt;A&gt;::value
4294    template &lt;class A&gt;
4295    typename deduce_vec&lt;A&gt;::type
4296    normalized( A const &amp; a );
4297
4298} }</code></pre>
4299</div>
4300</div>
4301<div class="dlist">
4302<dl>
4303<dt class="hdlist1">Effects: </dt>
4304<dd>
4305<p>As if:</p>
4306<div class="listingblock">
4307<div class="content">
4308<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">typename deduce_vec&lt;A&gt;::type tmp;
4309assign(tmp,a);
4310normalize(tmp);
4311return tmp;</code></pre>
4312</div>
4313</div>
4314</dd>
4315</dl>
4316</div>
4317<div class="admonitionblock note">
4318<table>
4319<tr>
4320<td class="icon">
4321<i class="fa icon-note" title="Note"></i>
4322</td>
4323<td class="content">
4324The <a href="#deduce_vec"><code>deduce_vec</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
4325</td>
4326</tr>
4327</table>
4328</div>
4329<hr>
4330</div>
4331<div class="sect3">
4332<h4 id="vec_normalize"><code>normalize</code></h4>
4333<div class="listingblock">
4334<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4335<div class="content">
4336<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4337
4338    //Only enabled if:
4339    //  is_vec&lt;A&gt;::value
4340    template &lt;class A&gt;
4341    void normalize( A &amp; a );
4342
4343} }</code></pre>
4344</div>
4345</div>
4346<div class="dlist">
4347<dl>
4348<dt class="hdlist1">Effects: </dt>
4349<dd>
4350<p>Normalizes <code>a</code>.</p>
4351</dd>
4352</dl>
4353</div>
4354<div class="paragraph">
4355<p>Ensures:</p>
4356</div>
4357<div class="paragraph">
4358<p><code>mag(a)==<a href="#scalar_traits">scalar_traits</a>&lt;typename <a href="#vec_traits">vec_traits&lt;A&gt;::scalar_type</a>&gt;::value(1)</code>.</p>
4359</div>
4360<div class="dlist">
4361<dl>
4362<dt class="hdlist1">Throws: </dt>
4363<dd>
4364<p>If the magnitude of <code>a</code> is zero, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
4365</dd>
4366</dl>
4367</div>
4368<hr>
4369</div>
4370<div class="sect3">
4371<h4 id="vec_dot"><code>dot</code></h4>
4372<div class="listingblock">
4373<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4374<div class="content">
4375<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4376
4377    //Only enabled if:
4378    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
4379    //  vec_traits&lt;A&gt;::dim==vec_traits&lt;B&gt;::dim
4380    template &lt;class A,class B&gt;
4381    typename deduce_scalar&lt;A,B&gt;::type
4382    dot( A const &amp; a, B const &amp; b );
4383
4384} }</code></pre>
4385</div>
4386</div>
4387<div class="dlist">
4388<dl>
4389<dt class="hdlist1">Returns: </dt>
4390<dd>
4391<p>The dot product of the vectors <code>a</code> and <code>b</code>.</p>
4392</dd>
4393</dl>
4394</div>
4395<div class="admonitionblock note">
4396<table>
4397<tr>
4398<td class="icon">
4399<i class="fa icon-note" title="Note"></i>
4400</td>
4401<td class="content">
4402The <a href="#deduce_scalar"><code>deduce_scalar</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
4403</td>
4404</tr>
4405</table>
4406</div>
4407<hr>
4408</div>
4409<div class="sect3">
4410<h4 id="vec_cross"><code>cross</code></h4>
4411<div class="listingblock">
4412<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4413<div class="content">
4414<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4415
4416    //Only enabled if:
4417    //  is_vec&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
4418    //  vec_traits&lt;A&gt;::dim==3 &amp;&amp; vec_traits&lt;B&gt;::dim==3
4419    template &lt;class A,class B&gt;
4420    typename deduce_vec2&lt;A,B,3&gt;::type
4421    cross( A const &amp; a, B const &amp; b );
4422
4423} }</code></pre>
4424</div>
4425</div>
4426<div class="dlist">
4427<dl>
4428<dt class="hdlist1">Returns: </dt>
4429<dd>
4430<p>The cross product of the vectors <code>a</code> and <code>b</code>.</p>
4431</dd>
4432</dl>
4433</div>
4434<div class="admonitionblock note">
4435<table>
4436<tr>
4437<td class="icon">
4438<i class="fa icon-note" title="Note"></i>
4439</td>
4440<td class="content">
4441The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
4442</td>
4443</tr>
4444</table>
4445</div>
4446<hr>
4447</div>
4448<div class="sect3">
4449<h4 id="zero_vec"><code>zero_vec</code></h4>
4450<div class="listingblock">
4451<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4452<div class="content">
4453<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4454
4455    template &lt;class T,int S&gt;
4456    -unspecified-return-type- zero_vec();
4457
4458} }</code></pre>
4459</div>
4460</div>
4461<div class="dlist">
4462<dl>
4463<dt class="hdlist1">Returns: </dt>
4464<dd>
4465<p>A read-only vector of unspecified type with <a href="#vec_traits"><code>scalar_type</code></a> <code>T</code> and size <code>S</code>, with all elements equal to <a href="#scalar_traits"><code>scalar_traits&lt;T&gt;::value(0)</code></a>.</p>
4466</dd>
4467</dl>
4468</div>
4469<hr>
4470</div>
4471<div class="sect3">
4472<h4 id="vec_set_zero"><code>set_zero</code></h4>
4473<div class="listingblock">
4474<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4475<div class="content">
4476<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4477
4478    //Only enabled if:
4479    //  is_vec&lt;A&gt;::value
4480    template &lt;class A&gt;
4481    void set_zero( A &amp; a );
4482
4483} }</code></pre>
4484</div>
4485</div>
4486<div class="dlist">
4487<dl>
4488<dt class="hdlist1">Effects: </dt>
4489<dd>
4490<p>As if:</p>
4491<div class="listingblock">
4492<div class="content">
4493<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(a,
4494  zero_vec&lt;
4495    typename vec_traits&lt;A&gt;::scalar_type,
4496    vec_traits&lt;A&gt;::dim&gt;());</code></pre>
4497</div>
4498</div>
4499</dd>
4500</dl>
4501</div>
4502<hr>
4503</div>
4504<div class="sect3">
4505<h4 id="vec_scalar_cast"><code>scalar_cast</code></h4>
4506<div class="listingblock">
4507<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4508<div class="content">
4509<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4510
4511    //Only enabled if: is_vec&lt;A&gt;::value
4512    template &lt;class Scalar,class A&gt;
4513    -unspecified-return_type- scalar_cast( A const &amp; a );
4514
4515} }</code></pre>
4516</div>
4517</div>
4518<div class="dlist">
4519<dl>
4520<dt class="hdlist1">Returns: </dt>
4521<dd>
4522<p>A read-only <a href="#view_proxy">view proxy</a> of <code>a</code> that looks like a vector of the same dimensions as <code>a</code>, but with <a href="#vec_traits"><code>scalar_type</code></a> <code>Scalar</code> and elements constructed from the corresponding elements of <code>a</code>.</p>
4523</dd>
4524</dl>
4525</div>
4526<hr>
4527</div>
4528<div class="sect3">
4529<h4 id="vref"><code>vref</code></h4>
4530<div class="listingblock">
4531<div class="title">#include &lt;boost/qvm/vec_operations.hpp&gt;</div>
4532<div class="content">
4533<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4534
4535    //Only enabled if: is_vec&lt;A&gt;::value
4536    template &lt;class A&gt;
4537    -unspecified-return-type- vref( A &amp; a );
4538
4539} }</code></pre>
4540</div>
4541</div>
4542<div class="dlist">
4543<dl>
4544<dt class="hdlist1">Returns: </dt>
4545<dd>
4546<p>An identity <a href="#view_proxy">view proxy</a> of <code>a</code>; that is, it simply accesses the elements of <code>a</code>.</p>
4547</dd>
4548</dl>
4549</div>
4550<div class="admonitionblock tip">
4551<table>
4552<tr>
4553<td class="icon">
4554<i class="fa icon-tip" title="Tip"></i>
4555</td>
4556<td class="content">
4557<code>vref</code> allows calling QVM operations when <code>a</code> is of built-in type, for example a plain old C array.
4558</td>
4559</tr>
4560</table>
4561</div>
4562<hr>
4563</div>
4564</div>
4565<div class="sect2">
4566<h3 id="_matrix_operations">Matrix Operations</h3>
4567<div class="sect3">
4568<h4 id="mat_assign"><code>assign</code></h4>
4569<div class="listingblock">
4570<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4571<div class="content">
4572<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4573
4574  //Only enabled if:
4575  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4576  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4577  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4578  template &lt;class A,class B&gt;
4579  A &amp; assign( A &amp; a, B const &amp; b );
4580
4581} }</code></pre>
4582</div>
4583</div>
4584<div class="dlist">
4585<dl>
4586<dt class="hdlist1">Effects: </dt>
4587<dd>
4588<p>Copies all elements of the matrix <code>b</code> to the matrix <code>a</code>.</p>
4589</dd>
4590<dt class="hdlist1">Returns: </dt>
4591<dd>
4592<p><code>a</code>.</p>
4593</dd>
4594</dl>
4595</div>
4596<hr>
4597</div>
4598<div class="sect3">
4599<h4 id="mat_convert_to"><code>convert_to</code></h4>
4600<div class="listingblock">
4601<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4602<div class="content">
4603<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4604
4605  //Only enabled if:
4606  //  is_mat&lt;R&gt;::value &amp;&amp; is_mat&lt;A&gt;::value &amp;&amp;
4607  //  mat_traits&lt;R&gt;::rows==mat_traits&lt;A&gt;::rows &amp;&amp;
4608  //  mat_traits&lt;R&gt;::cols==mat_traits&lt;A&gt;::cols
4609  template &lt;class R,class A&gt;
4610  R convert_to( A const &amp; a );
4611
4612} }</code></pre>
4613</div>
4614</div>
4615<div class="dlist">
4616<dl>
4617<dt class="hdlist1">Requires: </dt>
4618<dd>
4619<p><code>R</code> must be copyable.</p>
4620</dd>
4621</dl>
4622</div>
4623<div class="paragraph">
4624<p>Effects:</p>
4625</div>
4626<div class="paragraph">
4627<p>As if: <code>R r; <a href="#mat_assign">assign</a>(r,a); return r;</code></p>
4628</div>
4629<hr>
4630</div>
4631<div class="sect3">
4632<h4 id="mat_minus_eq_scalar"><code>operator-=</code></h4>
4633<div class="listingblock">
4634<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4635<div class="content">
4636<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4637
4638  //Only enabled if:
4639  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4640  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4641  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4642  template &lt;class A,class B&gt;
4643  A &amp; operator-=( A &amp; a, B const &amp; b );
4644
4645} }</code></pre>
4646</div>
4647</div>
4648<div class="dlist">
4649<dl>
4650<dt class="hdlist1">Effects: </dt>
4651<dd>
4652<p>Subtracts the elements of <code>b</code> from the corresponding elements of <code>a</code>.</p>
4653</dd>
4654<dt class="hdlist1">Returns: </dt>
4655<dd>
4656<p><code>a</code>.</p>
4657</dd>
4658</dl>
4659</div>
4660<hr>
4661</div>
4662<div class="sect3">
4663<h4 id="mat_minus_unary"><code>operator-</code> (unary)</h4>
4664<div class="listingblock">
4665<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4666<div class="content">
4667<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4668
4669  //Only enabled if: is_mat&lt;A&gt;::value
4670  template &lt;class A&gt;
4671  typename deduce_mat&lt;A&gt;::type
4672  operator-( A const &amp; a );
4673
4674} }</code></pre>
4675</div>
4676</div>
4677<div class="dlist">
4678<dl>
4679<dt class="hdlist1">Returns: </dt>
4680<dd>
4681<p>A matrix of the negated elements of <code>a</code>.</p>
4682</dd>
4683</dl>
4684</div>
4685<div class="admonitionblock note">
4686<table>
4687<tr>
4688<td class="icon">
4689<i class="fa icon-note" title="Note"></i>
4690</td>
4691<td class="content">
4692The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
4693</td>
4694</tr>
4695</table>
4696</div>
4697<hr>
4698</div>
4699<div class="sect3">
4700<h4 id="mat_minus"><code>operator-</code></h4>
4701<div class="listingblock">
4702<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4703<div class="content">
4704<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4705
4706  //Only enabled if:
4707  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4708  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4709  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4710  template &lt;class A,class B&gt;
4711  typename deduce_mat2&lt;A,B,mat_traits&lt;A&gt;::rows,mat_traits&lt;A&gt;::cols&gt;::type
4712  operator-( A const &amp; a, B const &amp; b );
4713
4714} }</code></pre>
4715</div>
4716</div>
4717<div class="dlist">
4718<dl>
4719<dt class="hdlist1">Returns: </dt>
4720<dd>
4721<p>A matrix of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> subtracted from the corresponding elements of <code>a</code>.</p>
4722</dd>
4723</dl>
4724</div>
4725<div class="admonitionblock note">
4726<table>
4727<tr>
4728<td class="icon">
4729<i class="fa icon-note" title="Note"></i>
4730</td>
4731<td class="content">
4732The <a href="#deduce_mat2"><code>deduce_mat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
4733</td>
4734</tr>
4735</table>
4736</div>
4737<hr>
4738</div>
4739<div class="sect3">
4740<h4 id="mat_plus_eq_scalar"><code>operator+=</code></h4>
4741<div class="listingblock">
4742<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4743<div class="content">
4744<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4745
4746  //Only enabled if:
4747  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4748  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4749  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4750  template &lt;class A,class B&gt;
4751  A &amp; operator+=( A &amp; a, B const &amp; b );
4752
4753} }</code></pre>
4754</div>
4755</div>
4756<div class="dlist">
4757<dl>
4758<dt class="hdlist1">Effects: </dt>
4759<dd>
4760<p>Adds the elements of <code>b</code> to the corresponding elements of <code>a</code>.</p>
4761</dd>
4762<dt class="hdlist1">Returns: </dt>
4763<dd>
4764<p><code>a</code>.</p>
4765</dd>
4766</dl>
4767</div>
4768<hr>
4769</div>
4770<div class="sect3">
4771<h4 id="mat_plus"><code>operator+</code></h4>
4772<div class="listingblock">
4773<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4774<div class="content">
4775<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4776
4777  //Only enabled if:
4778  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4779  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4780  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4781  template &lt;class A,class B&gt;
4782  typename deduce_mat2&lt;A,B,mat_traits&lt;A&gt;::rows,mat_traits&lt;A&gt;::cols&gt;::type
4783  operator+( A const &amp; a, B const &amp; b );
4784
4785} }</code></pre>
4786</div>
4787</div>
4788<div class="dlist">
4789<dl>
4790<dt class="hdlist1">Returns: </dt>
4791<dd>
4792<p>A matrix of the same size as <code>a</code> and <code>b</code>, with elements the elements of <code>b</code> added to the corresponding elements of <code>a</code>.</p>
4793</dd>
4794</dl>
4795</div>
4796<div class="admonitionblock note">
4797<table>
4798<tr>
4799<td class="icon">
4800<i class="fa icon-note" title="Note"></i>
4801</td>
4802<td class="content">
4803The <a href="#deduce_mat2"><code>deduce_mat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
4804</td>
4805</tr>
4806</table>
4807</div>
4808<hr>
4809</div>
4810<div class="sect3">
4811<h4 id="mat_div_eq_scalar"><code>operator/=</code> (scalar)</h4>
4812<div class="listingblock">
4813<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4814<div class="content">
4815<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4816
4817  //Only enabled if: is_mat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4818  template &lt;class A,class B&gt;
4819  A &amp; operator/=( A &amp; a, B b );
4820
4821} }</code></pre>
4822</div>
4823</div>
4824<div class="dlist">
4825<dl>
4826<dt class="hdlist1">Effects: </dt>
4827<dd>
4828<p>This operation divides a matrix by a scalar.</p>
4829</dd>
4830<dt class="hdlist1">Returns: </dt>
4831<dd>
4832<p><code>a</code>.</p>
4833</dd>
4834</dl>
4835</div>
4836<hr>
4837</div>
4838<div class="sect3">
4839<h4 id="mat_div_scalar"><code>operator/</code> (scalar)</h4>
4840<div class="listingblock">
4841<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4842<div class="content">
4843<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4844
4845  //Only enabled if: is_mat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4846  template &lt;class A,class B&gt;
4847  typename deduce_mat&lt;A&gt;::type
4848  operator/( A const &amp; a, B b );
4849
4850} }</code></pre>
4851</div>
4852</div>
4853<div class="dlist">
4854<dl>
4855<dt class="hdlist1">Returns: </dt>
4856<dd>
4857<p>A matrix that is the result of dividing the matrix <code>a</code> by the scalar <code>b</code>.</p>
4858</dd>
4859</dl>
4860</div>
4861<div class="admonitionblock note">
4862<table>
4863<tr>
4864<td class="icon">
4865<i class="fa icon-note" title="Note"></i>
4866</td>
4867<td class="content">
4868The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
4869</td>
4870</tr>
4871</table>
4872</div>
4873<hr>
4874</div>
4875<div class="sect3">
4876<h4 id="mat_mul_eq"><code>operator*=</code></h4>
4877<div class="listingblock">
4878<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4879<div class="content">
4880<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4881
4882  //Only enabled if:
4883  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4884  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols &amp;&amp;
4885  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
4886  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
4887  template &lt;class A,class B&gt;
4888  A &amp; operator*=( A &amp; a, B const &amp; b );
4889
4890} }</code></pre>
4891</div>
4892</div>
4893<div class="dlist">
4894<dl>
4895<dt class="hdlist1">Effects: </dt>
4896<dd>
4897<p>As if:</p>
4898<div class="listingblock">
4899<div class="content">
4900<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">A tmp(a);
4901a = tmp * b;
4902return a;</code></pre>
4903</div>
4904</div>
4905</dd>
4906</dl>
4907</div>
4908<hr>
4909</div>
4910<div class="sect3">
4911<h4 id="mat_mul_eq_scalar"><code>operator*=</code> (scalar)</h4>
4912<div class="listingblock">
4913<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4914<div class="content">
4915<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4916
4917  //Only enabled if: is_mat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4918  template &lt;class A,class B&gt;
4919  A &amp; operator*=( A &amp; a, B b );
4920
4921} }</code></pre>
4922</div>
4923</div>
4924<div class="dlist">
4925<dl>
4926<dt class="hdlist1">Effects: </dt>
4927<dd>
4928<p>This operation multiplies the matrix <code>a</code> matrix by the scalar <code>b</code>.</p>
4929</dd>
4930<dt class="hdlist1">Returns: </dt>
4931<dd>
4932<p><code>a</code>.</p>
4933</dd>
4934</dl>
4935</div>
4936<hr>
4937</div>
4938<div class="sect3">
4939<h4 id="mat_mul"><code>operator*</code></h4>
4940<div class="listingblock">
4941<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4942<div class="content">
4943<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4944
4945  //Only enabled if:
4946  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
4947  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::rows
4948  template &lt;class A,class B&gt;
4949  typename deduce_mat2&lt;A,B,mat_traits&lt;A&gt;::rows,mat_traits&lt;B&gt;::cols&gt;::type
4950  operator*( A const &amp; a, B const &amp; b );
4951
4952} }</code></pre>
4953</div>
4954</div>
4955<div class="dlist">
4956<dl>
4957<dt class="hdlist1">Returns: </dt>
4958<dd>
4959<p>The result of <a href="https://en.wikipedia.org/wiki/Matrix_multiplication">multiplying</a> the matrices <code>a</code> and <code>b</code>.</p>
4960</dd>
4961</dl>
4962</div>
4963<div class="admonitionblock note">
4964<table>
4965<tr>
4966<td class="icon">
4967<i class="fa icon-note" title="Note"></i>
4968</td>
4969<td class="content">
4970The <a href="#deduce_mat2"><code>deduce_mat2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
4971</td>
4972</tr>
4973</table>
4974</div>
4975<hr>
4976</div>
4977<div class="sect3">
4978<h4 id="mat_mul_scalar"><code>operator*</code> (scalar)</h4>
4979<div class="listingblock">
4980<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
4981<div class="content">
4982<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
4983
4984  //Only enabled if: is_mat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
4985  template &lt;class A,class B&gt;
4986  typename deduce_mat&lt;A&gt;::type
4987  operator*( A const &amp; a, B b );
4988
4989  //Only enabled if: is_scalar&lt;B&gt;::value &amp;&amp; is_mat&lt;A&gt;::value
4990  template &lt;class B,class A&gt;
4991  typename deduce_mat&lt;A&gt;::type
4992  operator*( B b, A const &amp; a );
4993
4994} }</code></pre>
4995</div>
4996</div>
4997<div class="dlist">
4998<dl>
4999<dt class="hdlist1">Returns: </dt>
5000<dd>
5001<p>A matrix that is the result of multiplying the matrix <code>a</code> by the scalar <code>b</code>.</p>
5002</dd>
5003</dl>
5004</div>
5005<div class="admonitionblock note">
5006<table>
5007<tr>
5008<td class="icon">
5009<i class="fa icon-note" title="Note"></i>
5010</td>
5011<td class="content">
5012The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
5013</td>
5014</tr>
5015</table>
5016</div>
5017<hr>
5018</div>
5019<div class="sect3">
5020<h4 id="mat_eq"><code>operator==</code></h4>
5021<div class="listingblock">
5022<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5023<div class="content">
5024<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5025
5026  //Only enabled if:
5027  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
5028  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
5029  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
5030  template &lt;class A,class B&gt;
5031  bool operator==( A const &amp; a, B const &amp; b );
5032
5033} }</code></pre>
5034</div>
5035</div>
5036<div class="dlist">
5037<dl>
5038<dt class="hdlist1">Returns: </dt>
5039<dd>
5040<p><code>true</code> if each element of <code>a</code> compares equal to its corresponding element of <code>b</code>, <code>false</code> otherwise.</p>
5041</dd>
5042</dl>
5043</div>
5044<hr>
5045</div>
5046<div class="sect3">
5047<h4 id="mat_neq"><code>operator!=</code></h4>
5048<div class="listingblock">
5049<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5050<div class="content">
5051<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5052
5053  //Only enabled if:
5054  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
5055  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
5056  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
5057  template &lt;class A,class B&gt;
5058  bool operator!=( A const &amp; a, B const &amp; b );
5059
5060} }</code></pre>
5061</div>
5062</div>
5063<div class="dlist">
5064<dl>
5065<dt class="hdlist1">Returns: </dt>
5066<dd>
5067<p><code>!( a <a href="#mat_eq">==</a> b )</code>.</p>
5068</dd>
5069</dl>
5070</div>
5071<hr>
5072</div>
5073<div class="sect3">
5074<h4 id="mat_cmp"><code>cmp</code></h4>
5075<div class="listingblock">
5076<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5077<div class="content">
5078<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5079
5080  //Only enabled if:
5081  //  is_mat&lt;A&gt;::value &amp;&amp; is_mat&lt;B&gt;::value &amp;&amp;
5082  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;B&gt;::rows &amp;&amp;
5083  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;B&gt;::cols
5084  template &lt;class A,class B,class Cmp&gt;
5085  bool cmp( A const &amp; a, B const &amp; b, Cmp pred );
5086
5087} }</code></pre>
5088</div>
5089</div>
5090<div class="dlist">
5091<dl>
5092<dt class="hdlist1">Returns: </dt>
5093<dd>
5094<p>Similar to <a href="#mat_eq"><code>operator==</code></a>, except that the individual elements of <code>a</code> and <code>b</code> are passed to the binary predicate <code>pred</code> for comparison.</p>
5095</dd>
5096</dl>
5097</div>
5098<hr>
5099</div>
5100<div class="sect3">
5101<h4 id="mat_inverse"><code>inverse</code></h4>
5102<div class="listingblock">
5103<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5104<div class="content">
5105<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5106
5107  //Only enabled if:
5108  //  is_mat&lt;A&gt;::value &amp;&amp; is_scalar&lt;B&gt;::value
5109  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5110
5111  template &lt;class A,class B&gt;
5112  typename deduce_mat&lt;A&gt;::type
5113  inverse( A const &amp; a, B det );
5114
5115  template &lt;class A&gt;
5116  typename deduce_mat&lt;A&gt;::type
5117  inverse( A const &amp; a );
5118
5119} }</code></pre>
5120</div>
5121</div>
5122<div class="dlist">
5123<dl>
5124<dt class="hdlist1">Preconditions: </dt>
5125<dd>
5126<p><code>det!=<a href="#scalar_traits">scalar_traits</a>&lt;typename <a href="#mat_traits">mat_traits&lt;A&gt;::scalar_type</a>&gt;::value(0)</code></p>
5127</dd>
5128<dt class="hdlist1">Returns: </dt>
5129<dd>
5130<p>Both overloads compute the inverse of <code>a</code>. The first overload takes the pre-computed determinant of <code>a</code>.</p>
5131</dd>
5132<dt class="hdlist1">Throws: </dt>
5133<dd>
5134<p>The second overload computes the determinant automatically and throws <a href="#zero_determinant_error"><code>zero_determinant_error</code></a> if the computed determinant is zero.</p>
5135</dd>
5136</dl>
5137</div>
5138<div class="admonitionblock note">
5139<table>
5140<tr>
5141<td class="icon">
5142<i class="fa icon-note" title="Note"></i>
5143</td>
5144<td class="content">
5145The <a href="#deduce_mat"><code>deduce_mat</code></a> template can be specialized to deduce the desired return type from the type <code>A</code>.
5146</td>
5147</tr>
5148</table>
5149</div>
5150<hr>
5151</div>
5152<div class="sect3">
5153<h4 id="zero_mat"><code>zero_mat</code></h4>
5154<div class="listingblock">
5155<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5156<div class="content">
5157<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5158
5159  template &lt;class T,int D&gt;
5160  -unspecified-return-type- zero_mat();
5161
5162  template &lt;class T,int R,int C&gt;
5163  -unspecified-return-type- zero_mat();
5164
5165} }</code></pre>
5166</div>
5167</div>
5168<div class="dlist">
5169<dl>
5170<dt class="hdlist1">Returns: </dt>
5171<dd>
5172<p>A read-only matrix of unspecified type with <a href="#mat_traits"><code>scalar_type</code></a> <code>T</code>, <code>R</code> rows and <code>C</code> columns (or <code>D</code> rows and <code>D</code> columns), with all elements equal to <a href="#scalar_traits"><code>scalar_traits&lt;T&gt;::value(0)</code></a>.</p>
5173</dd>
5174</dl>
5175</div>
5176<hr>
5177</div>
5178<div class="sect3">
5179<h4 id="mat_set_zero"><code>set_zero</code></h4>
5180<div class="listingblock">
5181<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5182<div class="content">
5183<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5184
5185  //Only enabled if:
5186  //  is_mat&lt;A&gt;::value
5187  template &lt;class A&gt;
5188  void set_zero( A &amp; a );
5189
5190} }</code></pre>
5191</div>
5192</div>
5193<div class="dlist">
5194<dl>
5195<dt class="hdlist1">Effects: </dt>
5196<dd>
5197<p>As if:</p>
5198<div class="listingblock">
5199<div class="content">
5200<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(a,
5201  zero_mat&lt;
5202    typename mat_traits&lt;A&gt;::scalar_type,
5203    mat_traits&lt;A&gt;::rows,
5204    mat_traits&lt;A&gt;::cols&gt;());</code></pre>
5205</div>
5206</div>
5207</dd>
5208</dl>
5209</div>
5210<hr>
5211</div>
5212<div class="sect3">
5213<h4 id="identity_mat"><code>identity_mat</code></h4>
5214<div class="listingblock">
5215<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5216<div class="content">
5217<pre class="nowrap">namespace boost { namespace qvm {
5218
5219  template &lt;class S,int D&gt;
5220  -unspecified-return-type- identity_mat();
5221
5222} }</pre>
5223</div>
5224</div>
5225<div class="dlist">
5226<dl>
5227<dt class="hdlist1">Returns: </dt>
5228<dd>
5229<p>An identity matrix of size <code>D</code> x <code>D</code> and scalar type <code>S</code>.</p>
5230</dd>
5231</dl>
5232</div>
5233<hr>
5234</div>
5235<div class="sect3">
5236<h4 id="mat_set_identity"><code>set_identity</code></h4>
5237<div class="listingblock">
5238<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5239<div class="content">
5240<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5241
5242  //Only enabled if:
5243  //  is_mat&lt;A&gt;::value &amp;&amp;
5244  //  mat_traits&lt;A&gt;::cols==mat_traits&lt;A&gt;::rows
5245  template &lt;class A&gt;
5246  void set_identity( A &amp; a );
5247
5248} }</code></pre>
5249</div>
5250</div>
5251<div class="dlist">
5252<dl>
5253<dt class="hdlist1">Effects: </dt>
5254<dd>
5255<p>As if:</p>
5256<div class="listingblock">
5257<div class="content">
5258<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
5259  a,
5260  identity_mat&lt;
5261    typename mat_traits&lt;A&gt;::scalar_type,
5262    mat_traits&lt;A&gt;::rows,
5263    mat_traits&lt;A&gt;::cols&gt;());</code></pre>
5264</div>
5265</div>
5266</dd>
5267</dl>
5268</div>
5269<hr>
5270</div>
5271<div class="sect3">
5272<h4 id="rot_mat"><code>rot_mat</code> / Euler angles</h4>
5273<div class="listingblock">
5274<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5275<div class="content">
5276<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5277
5278  //Only enabled if:
5279  //  is_vec&lt;A&gt;::value &amp;&amp; vec_traits&lt;A&gt;::dim==3
5280  template &lt;int Dim,class A,class Angle&gt;
5281  -unspecified-return-type-
5282  rot_mat( A const &amp; axis, Angle angle );
5283
5284  template &lt;int Dim,class Angle&gt;
5285  -unspecified-return-type-
5286  rot_mat_xzy( Angle x1, Angle z2, Angle y3 );
5287
5288  template &lt;int Dim,class Angle&gt;
5289  -unspecified-return-type-
5290  rot_mat_xyz( Angle x1, Angle y2, Angle z3 );
5291
5292  template &lt;int Dim,class Angle&gt;
5293  -unspecified-return-type-
5294  rot_mat_yxz( Angle y1, Angle x2, Angle z3 );
5295
5296  template &lt;int Dim,class Angle&gt;
5297  -unspecified-return-type-
5298  rot_mat_yzx( Angle y1, Angle z2, Angle x3 );
5299
5300  template &lt;int Dim,class Angle&gt;
5301  -unspecified-return-type-
5302  rot_mat_zyx( Angle z1, Angle y2, Angle x3 );
5303
5304  template &lt;int Dim,class Angle&gt;
5305  -unspecified-return-type-
5306  rot_mat_zxy( Angle z1, Angle x2, Angle y3 );
5307
5308  template &lt;int Dim,class Angle&gt;
5309  -unspecified-return-type-
5310  rot_mat_xzx( Angle x1, Angle z2, Angle x3 );
5311
5312  template &lt;int Dim,class Angle&gt;
5313  -unspecified-return-type-
5314  rot_mat_xyx( Angle x1, Angle y2, Angle x3 );
5315
5316  template &lt;int Dim,class Angle&gt;
5317  -unspecified-return-type-
5318  rot_mat_yxy( Angle y1, Angle x2, Angle y3 );
5319
5320  template &lt;int Dim,class Angle&gt;
5321  -unspecified-return-type-
5322  rot_mat_yzy( Angle y1, Angle z2, Angle y3 );
5323
5324  template &lt;int Dim,class Angle&gt;
5325  -unspecified-return-type-
5326  rot_mat_zyz( Angle z1, Angle y2, Angle z3 );
5327
5328  template &lt;int Dim,class Angle&gt;
5329  -unspecified-return-type-
5330  rot_mat_zxz( Angle z1, Angle y2, Angle z3 );
5331
5332} }</code></pre>
5333</div>
5334</div>
5335<div class="dlist">
5336<dl>
5337<dt class="hdlist1">Returns: </dt>
5338<dd>
5339<p>A matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns parameter, which performs a rotation around the <code>axis</code> at <code>angle</code> radians, or Tait–Bryan angles (x-y-z, y-z-x, z-x-y, x-z-y, z-y-x, y-x-z), or proper Euler angles (z-x-z, x-y-x, y-z-y, z-y-z, x-z-x, y-x-y). See <a href="https://en.wikipedia.org/wiki/Euler_angles">Euler angles</a>.</p>
5340</dd>
5341<dt class="hdlist1">Throws: </dt>
5342<dd>
5343<p>In case the axis vector has zero magnitude, throws <a href="#zero_magnitude_error"><code>zero_magnitude_error</code></a>.</p>
5344</dd>
5345</dl>
5346</div>
5347<div class="admonitionblock note">
5348<table>
5349<tr>
5350<td class="icon">
5351<i class="fa icon-note" title="Note"></i>
5352</td>
5353<td class="content">
5354These functions are not view proxies; they return a temp object.
5355</td>
5356</tr>
5357</table>
5358</div>
5359<hr>
5360</div>
5361<div class="sect3">
5362<h4 id="mat_set_rot"><code>set_rot</code> / Euler angles</h4>
5363<div class="listingblock">
5364<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5365<div class="content">
5366<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5367
5368  //Only enabled if:
5369  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5370  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols &amp;&amp;
5371  //  is_vec&lt;B&gt;::value &amp;&amp; vec_traits&lt;B&gt;::dim==3
5372  template &lt;class A&gt;
5373  void set_rot( A &amp; a, B const &amp; axis, typename vec_traits&lt;B&gt;::scalar_type angle );
5374
5375  //Only enabled if:
5376  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5377  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5378  template &lt;class A,class Angle&gt;
5379  void set_rot_xzy( A &amp; a, Angle x1, Angle z2, Angle y3 );
5380
5381  //Only enabled if:
5382  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5383  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5384  template &lt;class A,class Angle&gt;
5385  void set_rot_xyz( A &amp; a, Angle x1, Angle y2, Angle z3 );
5386
5387  //Only enabled if:
5388  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5389  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5390  template &lt;class A,class Angle&gt;
5391  void set_rot_yxz( A &amp; a, Angle y1, Angle x2, Angle z3 );
5392
5393  //Only enabled if:
5394  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5395  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5396  template &lt;class A,class Angle&gt;
5397  void set_rot_yzx( A &amp; a, Angle y1, Angle z2, Angle x3 );
5398
5399  //Only enabled if:
5400  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5401  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5402  template &lt;class A,class Angle&gt;
5403  void set_rot_zyx( A &amp; a, Angle z1, Angle y2, Angle x3 );
5404
5405  //Only enabled if:
5406  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5407  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5408  template &lt;class A,class Angle&gt;
5409  void set_rot_zxy( A &amp; a, Angle z1, Angle x2, Angle y3 );
5410
5411  //Only enabled if:
5412  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5413  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5414  template &lt;class A,class Angle&gt;
5415  void set_rot_xzx( A &amp; a, Angle x1, Angle z2, Angle x3 );
5416
5417  //Only enabled if:
5418  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5419  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5420  template &lt;class A,class Angle&gt;
5421  void set_rot_xyx( A &amp; a, Angle x1, Angle y2, Angle x3 );
5422
5423  //Only enabled if:
5424  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5425  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5426  template &lt;class A,class Angle&gt;
5427  void set_rot_yxy( A &amp; a, Angle y1, Angle x2, Angle y3 );
5428
5429  //Only enabled if:
5430  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5431  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5432  template &lt;class A,class Angle&gt;
5433  void set_rot_yzy( A &amp; a, Angle y1, Angle z2, Angle y3 );
5434
5435  //Only enabled if:
5436  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5437  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5438  template &lt;class A,class Angle&gt;
5439  void set_rot_zyz( A &amp; a, Angle z1, Angle y2, Angle z3 );
5440
5441  //Only enabled if:
5442  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5443  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5444  template &lt;class A,class Angle&gt;
5445  void set_rot_zxz( A &amp; a, Angle z1, Angle x2, Angle z3 );
5446
5447  //Only enabled if:
5448  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5449  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5450  template &lt;class A,class Angle&gt;
5451  void set_rot_xzy( A &amp; a, Angle x1, Angle z2, Angle y3 );
5452
5453} }</code></pre>
5454</div>
5455</div>
5456<div class="dlist">
5457<dl>
5458<dt class="hdlist1">Effects: </dt>
5459<dd>
5460<p>Assigns the return value of the corresponding <a href="#rot_mat"><code>rot_mat</code></a> function to <code>a</code>.</p>
5461</dd>
5462</dl>
5463</div>
5464<hr>
5465</div>
5466<div class="sect3">
5467<h4 id="mat_rotate"><code>rotate</code> / Euler angles</h4>
5468<div class="listingblock">
5469<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5470<div class="content">
5471<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5472
5473  //Only enabled if:
5474  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5475  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols &amp;&amp;
5476  //  is_vec&lt;B&gt;::value &amp;&amp; vec_traits&lt;B&gt;::dim==3
5477  template &lt;class A,class B&gt;
5478  void rotate( A &amp; a, B const &amp; axis, typename mat_traits&lt;A&gt;::scalar_type angle );
5479
5480  //Only enabled if:
5481  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5482  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5483  template &lt;class A,class Angle&gt;
5484  void rotate_xzy( A &amp; a, Angle x1, Angle z2, Angle y3 );
5485
5486  //Only enabled if:
5487  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5488  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5489  template &lt;class A,class Angle&gt;
5490  void rotate_xyz( A &amp; a, Angle x1, Angle y2, Angle z3 );
5491
5492  //Only enabled if:
5493  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5494  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5495  template &lt;class A,class Angle&gt;
5496  void rotate_yxz( A &amp; a, Angle y1, Angle x2, Angle z3 );
5497
5498  //Only enabled if:
5499  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5500  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5501  template &lt;class A,class Angle&gt;
5502  void rotate_yzx( A &amp; a, Angle y1, Angle z2, Angle x3 );
5503
5504  //Only enabled if:
5505  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5506  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5507  template &lt;class A,class Angle&gt;
5508  void rotate_zyx( A &amp; a, Angle z1, Angle y2, Angle x3 );
5509
5510  //Only enabled if:
5511  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5512  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5513  template &lt;class A,class Angle&gt;
5514  void rotate_zxy( A &amp; a, Angle z1, Angle x2, Angle y3 );
5515
5516  //Only enabled if:
5517  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5518  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5519  template &lt;class A,class Angle&gt;
5520  void rotate_xzx( A &amp; a, Angle x1, Angle z2, Angle x3 );
5521
5522  //Only enabled if:
5523  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5524  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5525  template &lt;class A,class Angle&gt;
5526  void rotate_xyx( A &amp; a, Angle x1, Angle y2, Angle x3 );
5527
5528  //Only enabled if:
5529  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5530  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5531  template &lt;class A,class Angle&gt;
5532  void rotate_yxy( A &amp; a, Angle y1, Angle x2, Angle y3 );
5533
5534  //Only enabled if:
5535  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5536  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5537  template &lt;class A,class Angle&gt;
5538  void rotate_yzy( A &amp; a, Angle y1, Angle z2, Angle y3 );
5539
5540  //Only enabled if:
5541  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5542  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5543  template &lt;class A,class Angle&gt;
5544  void rotate_zyz( A &amp; a, Angle z1, Angle y2, Angle z3 );
5545
5546  //Only enabled if:
5547  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5548  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5549  template &lt;class A,class Angle&gt;
5550  void rotate_zxz( A &amp; a, Angle z1, Angle x2, Angle z3 );
5551
5552} }</code></pre>
5553</div>
5554</div>
5555<div class="dlist">
5556<dl>
5557<dt class="hdlist1">Effects: </dt>
5558<dd>
5559<p>Multiplies the matrix <code>a</code> in-place by the return value of the corresponding <a href="#rot_mat"><code>rot_mat</code></a> function.</p>
5560</dd>
5561</dl>
5562</div>
5563<hr>
5564</div>
5565<div class="sect3">
5566<h4 id="rotx_mat"><code>rotx_mat</code></h4>
5567<div class="listingblock">
5568<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5569<div class="content">
5570<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5571
5572  template &lt;int Dim,class Angle&gt;
5573  -unspecified-return-type- rotx_mat( Angle const &amp; angle );
5574
5575} }</code></pre>
5576</div>
5577</div>
5578<div class="dlist">
5579<dl>
5580<dt class="hdlist1">Returns: </dt>
5581<dd>
5582<p>A <a href="#view_proxy">view proxy</a> matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns and scalar type <code>Angle</code>, which performs a rotation around the <code>X</code> axis at <code>angle</code> radians.</p>
5583</dd>
5584</dl>
5585</div>
5586<hr>
5587</div>
5588<div class="sect3">
5589<h4 id="mat_set_rotx"><code>set_rotx</code></h4>
5590<div class="listingblock">
5591<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5592<div class="content">
5593<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5594
5595  //Only enabled if:
5596  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5597  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5598  template &lt;class A&gt;
5599  void set_rotx( A &amp; a, typename mat_traits&lt;A&gt;::scalar_type angle );
5600
5601} }</code></pre>
5602</div>
5603</div>
5604<div class="dlist">
5605<dl>
5606<dt class="hdlist1">Effects: </dt>
5607<dd>
5608<p>As if:</p>
5609<div class="listingblock">
5610<div class="content">
5611<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
5612  a,
5613  rotx_mat&lt;mat_traits&lt;A&gt;::rows&gt;(angle));</code></pre>
5614</div>
5615</div>
5616</dd>
5617</dl>
5618</div>
5619<hr>
5620</div>
5621<div class="sect3">
5622<h4 id="mat_rotate_x"><code>rotate_x</code></h4>
5623<div class="listingblock">
5624<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5625<div class="content">
5626<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5627
5628  //Only enabled if:
5629  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5630  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5631  template &lt;class A&gt;
5632  void rotate_x( A &amp; a, typename mat_traits&lt;A&gt;::scalar_type angle );
5633
5634} }</code></pre>
5635</div>
5636</div>
5637<div class="dlist">
5638<dl>
5639<dt class="hdlist1">Effects: </dt>
5640<dd>
5641<p>As if: <code>a <a href="#mat_mul_eq">*=</a> <a href="#rotx_mat">rotx_mat</a>&lt;<a href="#mat_traits">mat_traits&lt;A&gt;::rows</a>&gt;(angle)</code>.</p>
5642</dd>
5643</dl>
5644</div>
5645<hr>
5646</div>
5647<div class="sect3">
5648<h4 id="roty_mat"><code>roty_mat</code></h4>
5649<div class="listingblock">
5650<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5651<div class="content">
5652<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5653
5654  template &lt;int Dim,class Angle&gt;
5655  -unspecified-return-type- roty_mat( Angle const &amp; angle );
5656
5657} }</code></pre>
5658</div>
5659</div>
5660<div class="dlist">
5661<dl>
5662<dt class="hdlist1">Returns: </dt>
5663<dd>
5664<p>A <a href="#view_proxy">view proxy</a> matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns and scalar type <code>Angle</code>, which performs a rotation around the <code>Y</code> axis at <code>angle</code> radians.</p>
5665</dd>
5666</dl>
5667</div>
5668<hr>
5669</div>
5670<div class="sect3">
5671<h4 id="mat_set_roty"><code>set_roty</code></h4>
5672<div class="listingblock">
5673<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5674<div class="content">
5675<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5676
5677  //Only enabled if:
5678  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5679  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5680  template &lt;class A&gt;
5681  void set_roty( A &amp; a, typename mat_traits&lt;A&gt;::scalar_type angle );
5682
5683} }</code></pre>
5684</div>
5685</div>
5686<div class="dlist">
5687<dl>
5688<dt class="hdlist1">Effects: </dt>
5689<dd>
5690<p>As if:</p>
5691<div class="listingblock">
5692<div class="content">
5693<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
5694  a,
5695  roty_mat&lt;mat_traits&lt;A&gt;::rows&gt;(angle));</code></pre>
5696</div>
5697</div>
5698</dd>
5699</dl>
5700</div>
5701<hr>
5702</div>
5703<div class="sect3">
5704<h4 id="mat_rotate_y"><code>rotate_y</code></h4>
5705<div class="listingblock">
5706<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5707<div class="content">
5708<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5709
5710  //Only enabled if:
5711  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5712  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5713  template &lt;class A&gt;
5714  void rotate_y( A &amp; a, typename mat_traits&lt;A&gt;::scalar_type angle );
5715
5716} }</code></pre>
5717</div>
5718</div>
5719<div class="dlist">
5720<dl>
5721<dt class="hdlist1">Effects: </dt>
5722<dd>
5723<p>As if: <code>a <a href="#mat_mul_eq">*=</a> <a href="#roty_mat">roty_mat</a>&lt;<a href="#mat_traits">mat_traits&lt;A&gt;::rows</a>&gt;(angle)</code>.</p>
5724</dd>
5725</dl>
5726</div>
5727<hr>
5728</div>
5729<div class="sect3">
5730<h4 id="rotz_mat"><code>rotz_mat</code></h4>
5731<div class="listingblock">
5732<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5733<div class="content">
5734<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5735
5736  template &lt;int Dim,class Angle&gt;
5737  -unspecified-return-type- rotz_mat( Angle const &amp; angle );
5738
5739} }</code></pre>
5740</div>
5741</div>
5742<div class="dlist">
5743<dl>
5744<dt class="hdlist1">Returns: </dt>
5745<dd>
5746<p>A <a href="#view_proxy">view proxy</a> matrix of unspecified type, of <code>Dim</code> rows and <code>Dim</code> columns and scalar type <code>Angle</code>, which performs a rotation around the <code>Z</code> axis at <code>angle</code> radians.</p>
5747</dd>
5748</dl>
5749</div>
5750<hr>
5751</div>
5752<div class="sect3">
5753<h4 id="mat_set_rotz"><code>set_rotz</code></h4>
5754<div class="listingblock">
5755<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5756<div class="content">
5757<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5758
5759  //Only enabled if:
5760  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5761  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5762  template &lt;class A&gt;
5763  void set_rotz( A &amp; a, typename mat_traits&lt;A&gt;::scalar_type angle );
5764
5765} }</code></pre>
5766</div>
5767</div>
5768<div class="dlist">
5769<dl>
5770<dt class="hdlist1">Effects: </dt>
5771<dd>
5772<p>As if:</p>
5773<div class="listingblock">
5774<div class="content">
5775<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">assign(
5776  a,
5777  rotz_mat&lt;mat_traits&lt;A&gt;::rows&gt;(angle));</code></pre>
5778</div>
5779</div>
5780</dd>
5781</dl>
5782</div>
5783<hr>
5784</div>
5785<div class="sect3">
5786<h4 id="mat_rotate_z"><code>rotate_z</code></h4>
5787<div class="listingblock">
5788<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5789<div class="content">
5790<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5791
5792  //Only enabled if:
5793  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3 &amp;&amp;
5794  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5795  template &lt;class A&gt;
5796  void rotate_z( A &amp; a, typename mat_traits&lt;A&gt;::scalar_type angle );
5797
5798} }</code></pre>
5799</div>
5800</div>
5801<div class="dlist">
5802<dl>
5803<dt class="hdlist1">Effects: </dt>
5804<dd>
5805<p>As if: <code>a <a href="#mat_mul_eq">*=</a> <a href="#rotz_mat">rotz_mat</a>&lt;<a href="#mat_traits">mat_traits&lt;A&gt;::rows</a>&gt;(angle)</code>.</p>
5806</dd>
5807</dl>
5808</div>
5809<hr>
5810</div>
5811<div class="sect3">
5812<h4 id="determinant"><code>determinant</code></h4>
5813<div class="listingblock">
5814<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5815<div class="content">
5816<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5817
5818  //Only enabled if:
5819  //  is_mat&lt;A&gt;::value &amp;&amp; mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols
5820  template &lt;class A&gt;
5821  mat_traits&lt;A&gt;::scalar_type
5822  determinant( A const &amp; a );
5823
5824} }</code></pre>
5825</div>
5826</div>
5827<div class="paragraph">
5828<p>This function computes the <a href="https://en.wikipedia.org/wiki/Determinant">determinant</a> of the square matrix <code>a</code>.</p>
5829</div>
5830<hr>
5831</div>
5832<div class="sect3">
5833<h4 id="perspective_lh"><code>perspective_lh</code></h4>
5834<div class="listingblock">
5835<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5836<div class="content">
5837<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5838
5839  template &lt;class T&gt;
5840  -unspecified-return-type-
5841  perspective_lh( T fov_y, T aspect, T zn, T zf );
5842
5843} }</code></pre>
5844</div>
5845</div>
5846<div class="dlist">
5847<dl>
5848<dt class="hdlist1">Returns: </dt>
5849<dd>
5850<p>A 4x4 projection matrix of unspecified type of the following form:</p>
5851<table class="tableblock frame-all grid-all" style="width: 50%;">
5852<colgroup>
5853<col style="width: 25%;">
5854<col style="width: 25%;">
5855<col style="width: 25%;">
5856<col style="width: 25%;">
5857</colgroup>
5858<tbody>
5859<tr>
5860<td class="tableblock halign-center valign-top"><div class="verse"> <code>xs</code></div></td>
5861<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5862<td class="tableblock halign-center valign-top"><div class="verse">  0</div></td>
5863<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5864</tr>
5865<tr>
5866<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5867<td class="tableblock halign-center valign-top"><div class="verse"> <code>ys</code></div></td>
5868<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5869<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5870</tr>
5871<tr>
5872<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5873<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5874<td class="tableblock halign-center valign-top"><div class="verse"> <code>zf</code>/(<code>zf</code>-<code>zn</code>)</div></td>
5875<td class="tableblock halign-center valign-top"><div class="verse">  -<code>zn</code>*<code>zf</code>/(<code>zf</code>-<code>zn</code>)</div></td>
5876</tr>
5877<tr>
5878<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5879<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5880<td class="tableblock halign-center valign-top"><div class="verse"> 1</div></td>
5881<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5882</tr>
5883</tbody>
5884</table>
5885<div class="paragraph">
5886<p>where <code>ys</code> = cot(<code>fov_y</code>/2) and <code>xs</code> = <code>ys</code>/<code>aspect</code>.</p>
5887</div>
5888</dd>
5889</dl>
5890</div>
5891<hr>
5892</div>
5893<div class="sect3">
5894<h4 id="perspective_rh"><code>perspective_rh</code></h4>
5895<div class="listingblock">
5896<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5897<div class="content">
5898<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5899
5900  template &lt;class T&gt;
5901  -unspecified-return-type-
5902  perspective_rh( T fov_y, T aspect, T zn, T zf );
5903
5904} }</code></pre>
5905</div>
5906</div>
5907<div class="dlist">
5908<dl>
5909<dt class="hdlist1">Returns: </dt>
5910<dd>
5911<p>A 4x4 projection matrix of unspecified type of the following form:</p>
5912<table class="tableblock frame-all grid-all" style="width: 50%;">
5913<colgroup>
5914<col style="width: 25%;">
5915<col style="width: 25%;">
5916<col style="width: 25%;">
5917<col style="width: 25%;">
5918</colgroup>
5919<tbody>
5920<tr>
5921<td class="tableblock halign-center valign-top"><div class="verse"> <code>xs</code></div></td>
5922<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5923<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5924<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5925</tr>
5926<tr>
5927<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5928<td class="tableblock halign-center valign-top"><div class="verse"> <code>ys</code></div></td>
5929<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5930<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5931</tr>
5932<tr>
5933<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5934<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5935<td class="tableblock halign-center valign-top"><div class="verse"> <code>zf</code>/(<code>zn</code>-<code>zf</code>)</div></td>
5936<td class="tableblock halign-center valign-top"><div class="verse"> <code>zn</code>*<code>zf</code>/(<code>zn</code>-<code>zf</code>)</div></td>
5937</tr>
5938<tr>
5939<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5940<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5941<td class="tableblock halign-center valign-top"><div class="verse"> -1</div></td>
5942<td class="tableblock halign-center valign-top"><div class="verse"> 0</div></td>
5943</tr>
5944</tbody>
5945</table>
5946<div class="paragraph">
5947<p>where <code>ys</code> = cot(<code>fov_y</code>/2), and <code>xs</code> = <code>ys</code>/<code>aspect</code>.</p>
5948</div>
5949</dd>
5950</dl>
5951</div>
5952<hr>
5953</div>
5954<div class="sect3">
5955<h4 id="mat_scalar_cast"><code>scalar_cast</code></h4>
5956<div class="listingblock">
5957<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5958<div class="content">
5959<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5960
5961  //Only enabled if: is_mat&lt;A&gt;::value
5962  template &lt;class Scalar,class A&gt;
5963  -unspecified-return_type- scalar_cast( A const &amp; a );
5964
5965} }</code></pre>
5966</div>
5967</div>
5968<div class="dlist">
5969<dl>
5970<dt class="hdlist1">Returns: </dt>
5971<dd>
5972<p>A read-only <a href="#view_proxy">view proxy</a> of <code>a</code> that looks like a matrix of the same dimensions as <code>a</code>, but with <a href="#mat_traits"><code>scalar_type</code></a> <code>Scalar</code> and elements constructed from the corresponding elements of <code>a</code>.</p>
5973</dd>
5974</dl>
5975</div>
5976<hr>
5977</div>
5978<div class="sect3">
5979<h4 id="mref"><code>mref</code></h4>
5980<div class="listingblock">
5981<div class="title">#include &lt;boost/qvm/mat_operations.hpp&gt;</div>
5982<div class="content">
5983<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
5984
5985  //Only enabled if: is_mat&lt;A&gt;::value
5986  template &lt;class A&gt;
5987  -unspecified-return-type- mref( A &amp; a );
5988
5989} }</code></pre>
5990</div>
5991</div>
5992<div class="dlist">
5993<dl>
5994<dt class="hdlist1">Returns: </dt>
5995<dd>
5996<p>An identity view proxy of <code>a</code>; that is, it simply accesses the elements of <code>a</code>.</p>
5997</dd>
5998</dl>
5999</div>
6000<div class="admonitionblock tip">
6001<table>
6002<tr>
6003<td class="icon">
6004<i class="fa icon-tip" title="Tip"></i>
6005</td>
6006<td class="content">
6007<code>mref</code> allows calling QVM operations when <code>a</code> is of built-in type, for example a plain old C array.
6008</td>
6009</tr>
6010</table>
6011</div>
6012<hr>
6013</div>
6014</div>
6015<div class="sect2">
6016<h3 id="_quaternion_vector_operations">Quaternion-Vector Operations</h3>
6017<div class="sect3">
6018<h4 id="quat_vec_mul"><code>operator*</code></h4>
6019<div class="listingblock">
6020<div class="title">#include &lt;boost/qvm/quat_vec_operations.hpp&gt;</div>
6021<div class="content">
6022<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6023
6024  //Only enabled if:
6025  //  is_mat&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
6026  //  mat_traits&lt;A&gt;::cols==vec_traits&lt;B&gt;::dim
6027  template &lt;class A,class B&gt;
6028  typename deduce_vec2&lt;A,B,mat_traits&lt;A&gt;::rows&gt;::type
6029  operator*( A const &amp; a, B const &amp; b );
6030
6031} }</code></pre>
6032</div>
6033</div>
6034<div class="dlist">
6035<dl>
6036<dt class="hdlist1">Returns: </dt>
6037<dd>
6038<p>The result of transforming the vector <code>b</code> by the quaternion <code>a</code>.</p>
6039</dd>
6040</dl>
6041</div>
6042<div class="admonitionblock note">
6043<table>
6044<tr>
6045<td class="icon">
6046<i class="fa icon-note" title="Note"></i>
6047</td>
6048<td class="content">
6049The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
6050</td>
6051</tr>
6052</table>
6053</div>
6054<hr>
6055</div>
6056</div>
6057<div class="sect2">
6058<h3 id="_matrix_vector_operations">Matrix-Vector Operations</h3>
6059<div class="sect3">
6060<h4 id="mat_vec_mul"><code>operator*</code></h4>
6061<div class="listingblock">
6062<div class="title">#include &lt;boost/qvm/vec_mat_operations.hpp&gt;</div>
6063<div class="content">
6064<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6065
6066  //Only enabled if:
6067  //  is_mat&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
6068  //  mat_traits&lt;A&gt;::cols==vec_traits&lt;B&gt;::dim
6069  template &lt;class A,class B&gt;
6070  typename deduce_vec2&lt;A,B,mat_traits&lt;A&gt;::rows&gt;::type
6071  operator*( A const &amp; a, B const &amp; b );
6072
6073} }</code></pre>
6074</div>
6075</div>
6076<div class="dlist">
6077<dl>
6078<dt class="hdlist1">Returns: </dt>
6079<dd>
6080<p>The result of multiplying the matrix <code>a</code> and the vector <code>b</code>, where <code>b</code> is interpreted as a matrix-column. The resulting matrix-row is returned as a vector type.</p>
6081</dd>
6082</dl>
6083</div>
6084<div class="admonitionblock note">
6085<table>
6086<tr>
6087<td class="icon">
6088<i class="fa icon-note" title="Note"></i>
6089</td>
6090<td class="content">
6091The <a href="#deduce_vec2"><code>deduce_vec2</code></a> template can be specialized to deduce the desired return type, given the types <code>A</code> and <code>B</code>.
6092</td>
6093</tr>
6094</table>
6095</div>
6096<hr>
6097</div>
6098<div class="sect3">
6099<h4 id="transform_vector"><code>transform_vector</code></h4>
6100<div class="listingblock">
6101<div class="title">#include &lt;boost/qvm/vec_mat_operations.hpp&gt;</div>
6102<div class="content">
6103<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6104
6105  //Only enabled if:
6106  //  is_mat&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
6107  //  mat_traits&lt;A&gt;::rows==4 &amp;&amp; mat_traits&lt;A&gt;::cols==4 &amp;&amp;
6108  //  vec_traits&lt;B&gt;::dim==3
6109  template &lt;class A,class B&gt;
6110  deduce_vec2&lt;A,B,3&gt; &gt;::type
6111  transform_vector( A const &amp; a, B const &amp; b );
6112
6113} }</code></pre>
6114</div>
6115</div>
6116<div class="dlist">
6117<dl>
6118<dt class="hdlist1">Effects: </dt>
6119<dd>
6120<p>As if: <code>return a <a href="#mat_vec_mul">*</a> <a href="#swizzling">XYZ0</a>(b)</code>.</p>
6121</dd>
6122</dl>
6123</div>
6124<hr>
6125</div>
6126<div class="sect3">
6127<h4 id="transform_point"><code>transform_point</code></h4>
6128<div class="listingblock">
6129<div class="title">#include &lt;boost/qvm/vec_mat_operations.hpp&gt;</div>
6130<div class="content">
6131<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6132
6133  //Only enabled if:
6134  //  is_mat&lt;A&gt;::value &amp;&amp; is_vec&lt;B&gt;::value &amp;&amp;
6135  //  mat_traits&lt;A&gt;::rows==4 &amp;&amp; mat_traits&lt;A&gt;::cols==4 &amp;&amp;
6136  //  vec_traits&lt;B&gt;::dim==3
6137  template &lt;class A,class B&gt;
6138  deduce_vec2&lt;A,B,3&gt; &gt;::type
6139  transform_point( A const &amp; a, B const &amp; b );
6140
6141} }</code></pre>
6142</div>
6143</div>
6144<div class="dlist">
6145<dl>
6146<dt class="hdlist1">Effects: </dt>
6147<dd>
6148<p>As if: <code>return a <a href="#mat_vec_mul">*</a> <a href="#swizzling">XYZ1</a>(b)</code>.</p>
6149</dd>
6150</dl>
6151</div>
6152<hr>
6153</div>
6154</div>
6155<div class="sect2">
6156<h3 id="_matrix_to_matrix_view_proxies">Matrix-to-Matrix View Proxies</h3>
6157<div class="sect3">
6158<h4 id="del_row"><code>del_row</code></h4>
6159<div class="listingblock">
6160<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6161<div class="content">
6162<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6163
6164  template &lt;int R&gt;
6165  -unspecified-return-type- del_row();
6166
6167} }</code></pre>
6168</div>
6169</div>
6170<div class="paragraph">
6171<p>The expression <code>del_row&lt;R&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with row <code>R</code> deleted.</p>
6172</div>
6173<hr>
6174</div>
6175<div class="sect3">
6176<h4 id="del_col"><code>del_col</code></h4>
6177<div class="listingblock">
6178<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6179<div class="content">
6180<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6181
6182  template &lt;int C&gt;
6183  -unspecified-return-type- del_col();
6184
6185} }</code></pre>
6186</div>
6187</div>
6188<div class="paragraph">
6189<p>The expression <code>del_col&lt;C&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with column <code>C</code> deleted.</p>
6190</div>
6191<hr>
6192</div>
6193<div class="sect3">
6194<h4 id="del_row_col"><code>del_row_col</code></h4>
6195<div class="listingblock">
6196<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6197<div class="content">
6198<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6199
6200  template &lt;int R,int C&gt;
6201  -unspecified-return-type- del_row_col();
6202
6203} }</code></pre>
6204</div>
6205</div>
6206<div class="paragraph">
6207<p>The expression <code>del_row_col&lt;R,C&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with row <code>R</code> and column <code>C</code> deleted.</p>
6208</div>
6209<hr>
6210</div>
6211<div class="sect3">
6212<h4 id="neg_row"><code>neg_row</code></h4>
6213<div class="listingblock">
6214<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6215<div class="content">
6216<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6217
6218  template &lt;int R&gt;
6219  -unspecified-return-type- neg_row();
6220
6221} }</code></pre>
6222</div>
6223</div>
6224<div class="paragraph">
6225<p>The expression <code>neg_row&lt;R&gt;(m)</code> returns a read-only <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with row <code>R</code> negated.</p>
6226</div>
6227<hr>
6228</div>
6229<div class="sect3">
6230<h4 id="neg_col"><code>neg_col</code></h4>
6231<div class="listingblock">
6232<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6233<div class="content">
6234<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6235
6236  template &lt;int C&gt;
6237  -unspecified-return-type- neg_col();
6238
6239} }</code></pre>
6240</div>
6241</div>
6242<div class="literalblock">
6243<div class="content">
6244<pre class="nowrap">The expression `neg_col&lt;C&gt;(m)` returns a read-only &lt;&lt;view_proxy,`view proxy`&gt;&gt; that looks like the matrix `m` with column `C` negated.</pre>
6245</div>
6246</div>
6247<hr>
6248</div>
6249<div class="sect3">
6250<h4 id="swap_rows"><code>swap_rows</code></h4>
6251<div class="listingblock">
6252<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6253<div class="content">
6254<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6255
6256  template &lt;int R1,int R2&gt;
6257  -unspecified-return-type- swap_rows();
6258
6259} }</code></pre>
6260</div>
6261</div>
6262<div class="paragraph">
6263<p>The expression <code>swap_rows&lt;R1,R2&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with rows <code>R1</code> and <code>R2</code> swapped.</p>
6264</div>
6265<hr>
6266</div>
6267<div class="sect3">
6268<h4 id="swap_cols"><code>swap_cols</code></h4>
6269<div class="listingblock">
6270<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6271<div class="content">
6272<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6273
6274  template &lt;int C1,int C2&gt;
6275  -unspecified-return-type- swap_cols();
6276
6277} }</code></pre>
6278</div>
6279</div>
6280<div class="paragraph">
6281<p>The expression <code>swap_cols&lt;C1,C2&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that looks like the matrix <code>m</code> with columns <code>C1</code> and <code>C2</code> swapped.</p>
6282</div>
6283<hr>
6284</div>
6285<div class="sect3">
6286<h4 id="transposed"><code>transposed</code></h4>
6287<div class="listingblock">
6288<div class="title">#include &lt;boost/qvm/map_mat_mat.hpp&gt;</div>
6289<div class="content">
6290<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6291
6292  -unspecified-return-type- transposed();
6293
6294} }</code></pre>
6295</div>
6296</div>
6297<div class="paragraph">
6298<p>The expression <code>transposed(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that transposes the matrix <code>m</code>.</p>
6299</div>
6300<hr>
6301</div>
6302</div>
6303<div class="sect2">
6304<h3 id="_vector_to_matrix_view_proxies">Vector-to-Matrix View Proxies</h3>
6305<div class="sect3">
6306<h4 id="col_mat"><code>col_mat</code></h4>
6307<div class="listingblock">
6308<div class="title">#include &lt;boost/qvm/map_vec_mat.hpp&gt;</div>
6309<div class="content">
6310<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6311
6312  //Only enabled if: is_vec&lt;A&gt;::value
6313  template &lt;iclass A&gt;
6314  -unspecified-return-type- col_mat( A &amp; a );
6315
6316} }</code></pre>
6317</div>
6318</div>
6319<div class="paragraph">
6320<p>The expression <code>col_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as a matrix-column.</p>
6321</div>
6322<hr>
6323</div>
6324<div class="sect3">
6325<h4 id="row_mat"><code>row_mat</code></h4>
6326<div class="listingblock">
6327<div class="title">#include &lt;boost/qvm/map_vec_mat.hpp&gt;</div>
6328<div class="content">
6329<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6330
6331  //Only enabled if: is_vec&lt;A&gt;::value
6332  template &lt;iclass A&gt;
6333  -unspecified-return-type- row_mat( A &amp; a );
6334
6335} }</code></pre>
6336</div>
6337</div>
6338<div class="paragraph">
6339<p>The expression <code>row_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as a matrix-row.</p>
6340</div>
6341<hr>
6342</div>
6343<div class="sect3">
6344<h4 id="translation_mat"><code>translation_mat</code></h4>
6345<div class="listingblock">
6346<div class="title">#include &lt;boost/qvm/map_vec_mat.hpp&gt;</div>
6347<div class="content">
6348<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6349
6350  //Only enabled if: is_vec&lt;A&gt;::value
6351  template &lt;iclass A&gt;
6352  -unspecified-return-type- translation_mat( A &amp; a );
6353
6354} }</code></pre>
6355</div>
6356</div>
6357<div class="paragraph">
6358<p>The expression <code>translation_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as translation matrix of size 1 + <a href="#vec_traits"><code>vec_traits&lt;A&gt;::dim</code></a>.</p>
6359</div>
6360<hr>
6361</div>
6362<div class="sect3">
6363<h4 id="diag_mat"><code>diag_mat</code></h4>
6364<div class="listingblock">
6365<div class="title">#include &lt;boost/qvm/map_vec_mat.hpp&gt;</div>
6366<div class="content">
6367<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6368
6369  //Only enabled if: is_vec&lt;A&gt;::value
6370  template &lt;iclass A&gt;
6371  -unspecified-return-type- diag_mat( A &amp; a );
6372
6373} }</code></pre>
6374</div>
6375</div>
6376<div class="paragraph">
6377<p>The expression <code>diag_mat(v)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the vector <code>v</code> as a square matrix of the same dimensions in which the elements of <code>v</code> appear as the main diagonal and all other elements are zero.</p>
6378</div>
6379<div class="admonitionblock tip">
6380<table>
6381<tr>
6382<td class="icon">
6383<i class="fa icon-tip" title="Tip"></i>
6384</td>
6385<td class="content">
6386If <code>v</code> is a 3D vector, the expression <code>diag_mat(XYZ1(v))</code> can be used as a scaling 4D matrix.
6387</td>
6388</tr>
6389</table>
6390</div>
6391<hr>
6392</div>
6393</div>
6394<div class="sect2">
6395<h3 id="_matrix_to_vector_view_proxies">Matrix-to-Vector View Proxies</h3>
6396<div class="sect3">
6397<h4 id="col"><code>col</code></h4>
6398<div class="listingblock">
6399<div class="title">#include &lt;boost/qvm/map_mat_vec.hpp&gt;</div>
6400<div class="content">
6401<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6402
6403  //Only enabled if: is_mat&lt;A&gt;::value
6404  template &lt;int C,class A&gt;
6405  -unspecified-return-type- col( A &amp; a );
6406
6407} }</code></pre>
6408</div>
6409</div>
6410<div class="paragraph">
6411<p>The expression <code>col&lt;C&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses column <code>C</code> of the matrix <code>m</code> as a vector.</p>
6412</div>
6413<hr>
6414</div>
6415<div class="sect3">
6416<h4 id="row"><code>row</code></h4>
6417<div class="listingblock">
6418<div class="title">#include &lt;boost/qvm/map_mat_vec.hpp&gt;</div>
6419<div class="content">
6420<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6421
6422  //Only enabled if: is_mat&lt;A&gt;::value
6423  template &lt;int C,class A&gt;
6424  -unspecified-return-type- row( A &amp; a );
6425
6426} }</code></pre>
6427</div>
6428</div>
6429<div class="paragraph">
6430<p>The expression <code>row&lt;R&gt;(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses row <code>R</code> of the matrix <code>m</code> as a vector.</p>
6431</div>
6432<hr>
6433</div>
6434<div class="sect3">
6435<h4 id="diag"><code>diag</code></h4>
6436<div class="listingblock">
6437<div class="title">#include &lt;boost/qvm/map_mat_vec.hpp&gt;</div>
6438<div class="content">
6439<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6440
6441  //Only enabled if: is_mat&lt;A&gt;::value
6442  template &lt;class A&gt;
6443  -unspecified-return-type- diag( A &amp; a );
6444
6445} }</code></pre>
6446</div>
6447</div>
6448<div class="paragraph">
6449<p>The expression <code>diag(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the main diagonal of the matrix <code>m</code> as a vector.</p>
6450</div>
6451<hr>
6452</div>
6453<div class="sect3">
6454<h4 id="translation"><code>translation</code></h4>
6455<div class="listingblock">
6456<div class="title">#include &lt;boost/qvm/map_mat_vec.hpp&gt;</div>
6457<div class="content">
6458<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6459
6460  //Only enabled if:
6461  //  is_mat&lt;A&gt;::value &amp;&amp;
6462  //  mat_traits&lt;A&gt;::rows==mat_traits&lt;A&gt;::cols &amp;&amp; mat_traits&lt;A&gt;::rows&gt;=3
6463  template &lt;class A&gt;
6464  -unspecified-return-type- translation( A &amp; a );
6465
6466} }</code></pre>
6467</div>
6468</div>
6469<div class="paragraph">
6470<p>The expression <code>translation(m)</code> returns an lvalue <a href="#view_proxy">view proxy</a> that accesses the translation component of the square matrix <code>m</code>, which is a vector of size <code>D</code>-1, where <code>D</code> is the size of <code>m</code>.</p>
6471</div>
6472<hr>
6473</div>
6474</div>
6475<div class="sect2">
6476<h3 id="_exceptions">Exceptions</h3>
6477<div class="sect3">
6478<h4 id="error"><code>error</code></h4>
6479<div class="listingblock">
6480<div class="title">#include &lt;boost/qvm/error.hpp&gt;</div>
6481<div class="content">
6482<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6483
6484  struct error: virtual boost::exception, virtual std::exception { };
6485
6486} }</code></pre>
6487</div>
6488</div>
6489<div class="paragraph">
6490<p>This is the base for all exceptions thorwn by QVM.</p>
6491</div>
6492<hr>
6493</div>
6494<div class="sect3">
6495<h4 id="zero_magnitude_error"><code>zero_magnitude_error</code></h4>
6496<div class="listingblock">
6497<div class="title">#include &lt;boost/qvm/error.hpp&gt;</div>
6498<div class="content">
6499<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6500
6501  struct zero_magnitude_error: virtual error { };
6502
6503} }</code></pre>
6504</div>
6505</div>
6506<div class="paragraph">
6507<p>This exception indicates that an operation requires a vector or a quaternion with non-zero magnitude, but the computed magnitude is zero.</p>
6508</div>
6509<hr>
6510</div>
6511<div class="sect3">
6512<h4 id="zero_determinant_error"><code>zero_determinant_error</code></h4>
6513<div class="listingblock">
6514<div class="title">#include &lt;boost/qvm/error.hpp&gt;</div>
6515<div class="content">
6516<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6517
6518  struct zero_determinant_error: virtual error { };
6519
6520} }</code></pre>
6521</div>
6522</div>
6523<div class="paragraph">
6524<p>This exception indicates that an operation requires a matrix with non-zero determinant, but the computed determinant is zero.</p>
6525</div>
6526<hr>
6527</div>
6528</div>
6529<div class="sect2">
6530<h3 id="_macros_and_configuration_boost_qvm">Macros and Configuration: BOOST_QVM_</h3>
6531<div class="sect3">
6532<h4 id="BOOST_QVM_INLINE"><code>INLINE</code></h4>
6533<div class="sect4">
6534<h5 id="_boost_qvm_inline"><code>BOOST_QVM_INLINE</code></h5>
6535<div class="listingblock">
6536<div class="title">#include &lt;boost/qvm/inline.hpp&gt;</div>
6537<div class="content">
6538<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6539
6540  #ifndef BOOST_QVM_INLINE
6541  #define BOOST_QVM_INLINE inline
6542  #endif
6543
6544} }</code></pre>
6545</div>
6546</div>
6547<div class="paragraph">
6548<p>This macro is not used directly by QVM, except as the default value of other macros from <code>&lt;boost/qvm/inline.hpp&gt;</code>. A user-defined <code>BOOST_QVM_INLINE</code> should expand to a value that is valid substitution of the <code>inline</code> keyword in function definitions.</p>
6549</div>
6550<hr>
6551</div>
6552</div>
6553<div class="sect3">
6554<h4 id="BOOST_QVM_FORCE_INLINE"><code>FORCE_INLINE</code></h4>
6555<div class="sect4">
6556<h5 id="_boost_qvm_force_inline"><code>BOOST_QVM_FORCE_INLINE</code></h5>
6557<div class="listingblock">
6558<div class="title">#include &lt;boost/qvm/inline.hpp&gt;</div>
6559<div class="content">
6560<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6561
6562  #ifndef BOOST_QVM_FORCE_INLINE
6563  #define BOOST_QVM_FORCE_INLINE /*platform-specific*/
6564  #endif
6565
6566} }</code></pre>
6567</div>
6568</div>
6569<div class="paragraph">
6570<p>This macro is not used directly by QVM, except as the default value of other macros from <code>&lt;boost/qvm/inline.hpp&gt;</code>. A user-defined <code>BOOST_QVM_FORCE_INLINE</code> should expand to a value that is valid substitution of the <code>inline</code> keyword in function definitions, to indicate that the compiler must inline the function. Of course, actual inlining may or may not occur.</p>
6571</div>
6572<hr>
6573</div>
6574</div>
6575<div class="sect3">
6576<h4 id="BOOST_QVM_INLINE_TRIVIAL"><code>INLINE_TRIVIAL</code></h4>
6577<div class="sect4">
6578<h5 id="_boost_qvm_inline_trivial"><code>BOOST_QVM_INLINE_TRIVIAL</code></h5>
6579<div class="listingblock">
6580<div class="title">#include &lt;boost/qvm/inline.hpp&gt;</div>
6581<div class="content">
6582<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6583
6584  #ifndef BOOST_QVM_INLINE_TRIVIAL
6585  #define BOOST_QVM_INLINE_TRIVIAL BOOST_QVM_FORCE_INLINE
6586  #endif
6587
6588} }</code></pre>
6589</div>
6590</div>
6591<div class="paragraph">
6592<p>QVM uses <code>BOOST_QVM_INLINE_TRIVIAL</code> in definitions of functions that are not critical for the overall performance of the library but are extremely simple (such as one-liners) and therefore should always be inlined.</p>
6593</div>
6594<hr>
6595</div>
6596</div>
6597<div class="sect3">
6598<h4 id="BOOST_QVM_INLINE_CRITICAL"><code>INLINE_CRITICAL</code></h4>
6599<div class="sect4">
6600<h5 id="_boost_qvm_inline_critical"><code>BOOST_QVM_INLINE_CRITICAL</code></h5>
6601<div class="listingblock">
6602<div class="title">#include &lt;boost/qvm/inline.hpp&gt;</div>
6603<div class="content">
6604<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6605
6606  #ifndef BOOST_QVM_INLINE_CRITICAL
6607  #define BOOST_QVM_INLINE_CRITICAL BOOST_QVM_FORCE_INLINE
6608  #endif
6609
6610} }</code></pre>
6611</div>
6612</div>
6613<div class="paragraph">
6614<p>QVM uses <code>BOOST_QVM_INLINE_CRITICAL</code> in definitions of functions that are critical for the overall performance of the library, such as functions that access individual vector and matrix elements.</p>
6615</div>
6616<hr>
6617</div>
6618</div>
6619<div class="sect3">
6620<h4 id="BOOST_QVM_INLINE_OPERATIONS"><code>INLINE_OPERATIONS</code></h4>
6621<div class="sect4">
6622<h5 id="_boost_qvm_inline_operations"><code>BOOST_QVM_INLINE_OPERATIONS</code></h5>
6623<div class="listingblock">
6624<div class="title">#include &lt;boost/qvm/inline.hpp&gt;</div>
6625<div class="content">
6626<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6627
6628  #ifndef BOOST_QVM_INLINE_OPERATIONS
6629  #define BOOST_QVM_INLINE_OPERATIONS BOOST_QVM_INLINE
6630  #endif
6631
6632} }</code></pre>
6633</div>
6634</div>
6635<div class="paragraph">
6636<p>QVM uses <code>BOOST_QVM_INLINE_OPERATIONS</code> in definitions of functions that implement various high-level operations, such as matrix multiplication, computing the magnitude of a vector, etc.</p>
6637</div>
6638<hr>
6639</div>
6640</div>
6641<div class="sect3">
6642<h4 id="BOOST_QVM_INLINE_RECURSION"><code>INLINE_RECURSION</code></h4>
6643<div class="sect4">
6644<h5 id="_boost_qvm_inline_recursion"><code>BOOST_QVM_INLINE_RECURSION</code></h5>
6645<div class="listingblock">
6646<div class="title">#include &lt;boost/qvm/inline.hpp&gt;</div>
6647<div class="content">
6648<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6649
6650  #ifndef BOOST_QVM_INLINE_RECURSION
6651  #define BOOST_QVM_INLINE_RECURSION BOOST_QVM_INLINE_OPERATIONS
6652  #endif
6653
6654} }</code></pre>
6655</div>
6656</div>
6657<div class="paragraph">
6658<p>QVM uses <code>BOOST_QVM_INLINE_RECURSION</code> in definitions of recursive functions that are not critical for the overall performance of the library (definitions of all critical functions, including critical recursive functions, use <a href="#BOOST_QVM_INLINE_CRITICAL"><code>BOOST_QVM_INLINE_CRITICAL</code></a>).</p>
6659</div>
6660<hr>
6661</div>
6662</div>
6663<div class="sect3">
6664<h4 id="BOOST_QVM_ASSERT"><code>ASSERT</code></h4>
6665<div class="sect4">
6666<h5 id="_boost_qvm_assert"><code>BOOST_QVM_ASSERT</code></h5>
6667<div class="listingblock">
6668<div class="title">#include &lt;boost/qvm/assert.hpp&gt;</div>
6669<div class="content">
6670<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6671
6672#ifndef BOOST_QVM_ASSERT
6673#include &lt;boost/assert.hpp&gt;
6674#define BOOST_QVM_ASSERT BOOST_ASSERT
6675#endif
6676
6677} }</code></pre>
6678</div>
6679</div>
6680<div class="paragraph">
6681<p>This is the macro QVM uses to assert on precondition violations and logic errors. A user-defined <code>BOOST_QVM_ASSERT</code> should have the semantics of the standard <code>assert</code>.</p>
6682</div>
6683<hr>
6684</div>
6685</div>
6686<div class="sect3">
6687<h4 id="BOOST_QVM_STATIC_ASSERT"><code>STATIC_ASSERT</code></h4>
6688<div class="sect4">
6689<h5 id="_boost_qvm_static_assert"><code>BOOST_QVM_STATIC_ASSERT</code></h5>
6690<div class="listingblock">
6691<div class="title">#include &lt;boost/qvm/static_assert.hpp&gt;</div>
6692<div class="content">
6693<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6694
6695  #ifndef BOOST_QVM_STATIC_ASSERT
6696  #include &lt;boost/static_assert.hpp&gt;
6697  #define BOOST_QVM_STATIC_ASSERT BOOST_STATIC_ASSERT
6698  #endif
6699
6700} }</code></pre>
6701</div>
6702</div>
6703<div class="paragraph">
6704<p>All static assertions in QVM use the <code>BOOST_QVM_STATIC_ASSERT</code> macro.</p>
6705</div>
6706<hr>
6707</div>
6708</div>
6709<div class="sect3">
6710<h4 id="BOOST_QVM_THROW_EXCEPTION"><code>THROW_EXCEPTION</code></h4>
6711<div class="sect4">
6712<h5 id="_boost_qvm_throw_exception"><code>BOOST_QVM_THROW_EXCEPTION</code></h5>
6713<div class="listingblock">
6714<div class="title">#include &lt;boost/qvm/throw_exception.hpp&gt;</div>
6715<div class="content">
6716<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace boost { namespace qvm {
6717
6718  #ifndef BOOST_QVM_THROW_EXCEPTION
6719  #include &lt;boost/throw_exception.hpp&gt;
6720  #define BOOST_QVM_THROW_EXCEPTION BOOST_THROW_EXCEPTION
6721  #endif
6722
6723} }</code></pre>
6724</div>
6725</div>
6726<div class="paragraph">
6727<p>This macro is used whenever QVM throws an exception. Users who override the standard <code>BOOST_QVM_THROW_EXCEPTION</code> behavior must ensure that when invoked, the substituted implementation does not return control to the caller. Below is a list of all QVM functions that invoke <code>BOOST_QVM_THROW_EXCEPTION</code>:</p>
6728</div>
6729<div class="ulist">
6730<ul>
6731<li>
6732<p>Quaternion operations:</p>
6733<div class="ulist">
6734<ul>
6735<li>
6736<p><a href="#quat_inverse"><code>inverse</code></a></p>
6737</li>
6738<li>
6739<p><a href="#rot_quat"><code>rot_quat</code></a></p>
6740</li>
6741<li>
6742<p><a href="#quat_normalize"><code>normalize</code></a></p>
6743</li>
6744<li>
6745<p><a href="#quat_normalized"><code>normalized</code></a></p>
6746</li>
6747</ul>
6748</div>
6749</li>
6750<li>
6751<p>Vector operations:</p>
6752<div class="ulist">
6753<ul>
6754<li>
6755<p><a href="#vec_normalize"><code>normalize</code></a></p>
6756</li>
6757<li>
6758<p><a href="#vec_normalized"><code>normalized</code></a></p>
6759</li>
6760</ul>
6761</div>
6762</li>
6763<li>
6764<p>Matrix operations:</p>
6765<div class="ulist">
6766<ul>
6767<li>
6768<p><a href="#mat_inverse"><code>inverse</code></a></p>
6769</li>
6770<li>
6771<p><a href="#rot_mat"><code>rot_mat</code></a></p>
6772</li>
6773</ul>
6774</div>
6775</li>
6776</ul>
6777</div>
6778</div>
6779</div>
6780</div>
6781</div>
6782</div>
6783<div class="sect1">
6784<h2 id="rationale">Design Rationale</h2>
6785<div class="sectionbody">
6786<div class="paragraph">
6787<p>C&#43;&#43; is ideal for 3D graphics and other domains that require 3D transformations: define vector and matrix types and then overload the appropriate operators to implement the standard algebraic operations. Because this is relatively straight-forward, there are many libraries that do this, each providing custom vector and matrix types, and then defining the same operations (e.g. matrix multiply) for these types.</p>
6788</div>
6789<div class="paragraph">
6790<p>Often these libraries are part of a higher level system. For example, video game programmers typically use one set of vector/matrix types with the rendering engine, and another with the physics simulation engine.</p>
6791</div>
6792<div class="paragraph">
6793<p>QVM proides interoperability between all these different types and APIs by decoupling the standard algebraic functions from the types they operate on&#8201;&#8212;&#8201;without compromising type safety. The operations work on any type for which proper traits have been specialized. Using QVM, there is no need to translate between the different quaternion, vector or matrix types; they can be mixed in the same expression safely and efficiently.</p>
6794</div>
6795<div class="paragraph">
6796<p>This design enables QVM to generate types and adaptors at compile time, compatible with any other QVM or user-defined type. For example, transposing a matrix needs not store the result: rather than modifying its argument or returning a new object, it simply binds the original matrix object through a generated type which remaps element access on the fly.</p>
6797</div>
6798<div class="paragraph">
6799<p>In addition, QVM can be helpful in selectively optimizing individual types or operations for maximum performance where that matters. For example, users can overload a specific operation for specific types, or define highly optimized, possibly platform-specific or for some reason cumbersome to use types, then mix and match them with more user-friendly types in parts of the program where performance isn&#8217;t critical.</p>
6800</div>
6801</div>
6802</div>
6803<div class="sect1">
6804<h2 id="_code_generator">Code Generator</h2>
6805<div class="sectionbody">
6806<div class="paragraph">
6807<p>While QVM defines generic functions that operate on matrix and vector types of arbitrary static dimensions, it also provides a code generator that can be used to create compatible header files that define much simpler specializations of these functions for specific dimensions. This is useful during debugging since the generated code is much easier to read than the template metaprogramming-heavy generic implementations. It is also potentially friendlier to the optimizer.</p>
6808</div>
6809<div class="paragraph">
6810<p>The code generator is a command-line utility program. Its source code can be found in the <code>boost/libs/qvm/gen</code> directory. It was used to generate the following headers that ship with QVM:</p>
6811</div>
6812<div class="ulist">
6813<ul>
6814<li>
6815<p>2D, 3D and 4D matrix operations:</p>
6816<div class="ulist">
6817<ul>
6818<li>
6819<p><code>boost/qvm/gen/mat_operations2.hpp</code> (matrices of size 2x2, 2x1 and 1x2, included by <code>boost/qvm/mat_operations2.hpp</code>)</p>
6820</li>
6821<li>
6822<p><code>boost/qvm/gen/mat_operations3.hpp</code> (matrices of size 3x3, 3x1 and 1x3, included by <code>boost/qvm/mat_operations3.hpp</code>)</p>
6823</li>
6824<li>
6825<p><code>boost/qvm/gen/mat_operations4.hpp</code> (matrices of size 4x4, 4x1 and 1x4, included by <code>boost/qvm/mat_operations4.hpp</code>)</p>
6826</li>
6827</ul>
6828</div>
6829</li>
6830<li>
6831<p>2D, 3D and 4D vector operations:</p>
6832<div class="ulist">
6833<ul>
6834<li>
6835<p><code>boost/qvm/gen/v2.hpp</code> (included by <code>boost/qvm/vec_operations2.hpp</code>)</p>
6836</li>
6837<li>
6838<p><code>boost/qvm/gen/v3.hpp</code> (included by <code>boost/qvm/vec_operations3.hpp</code>)</p>
6839</li>
6840<li>
6841<p><code>boost/qvm/gen/v4.hpp</code> (included by <code>boost/qvm/vec_operations4.hpp</code>)</p>
6842</li>
6843</ul>
6844</div>
6845</li>
6846<li>
6847<p>2D, 3D and 4D vector-matrix operations:</p>
6848<div class="ulist">
6849<ul>
6850<li>
6851<p><code>boost/qvm/gen/vm2.hpp</code> (included by <code>boost/qvm/vec_mat_operations2.hpp</code>)</p>
6852</li>
6853<li>
6854<p><code>boost/qvm/gen/vm3.hpp</code> (included by <code>boost/qvm/vec_mat_operations3.hpp</code>)</p>
6855</li>
6856<li>
6857<p><code>boost/qvm/gen/vm4.hpp</code> (included by <code>boost/qvm/vec_mat_operations4.hpp</code>)</p>
6858</li>
6859</ul>
6860</div>
6861</li>
6862<li>
6863<p>2D, 3D and 4D vector swizzling operations:</p>
6864<div class="ulist">
6865<ul>
6866<li>
6867<p><code>boost/qvm/gen/sw2.hpp</code> (included by <code>boost/qvm/swizzle2.hpp</code>)</p>
6868</li>
6869<li>
6870<p><code>boost/qvm/gen/sw3.hpp</code> (included by <code>boost/qvm/swizzle3.hpp</code>)</p>
6871</li>
6872<li>
6873<p><code>boost/qvm/gen/sw4.hpp</code> (included by <code>boost/qvm/swizzle4.hpp</code>)</p>
6874</li>
6875</ul>
6876</div>
6877</li>
6878</ul>
6879</div>
6880<div class="paragraph">
6881<p>Any such generated headers must be included before the corresponding generic header file is included. For example, if one creates a header <code>boost/qvm/gen/m5.hpp</code>, it must be included before <code>boost/qvm/mat_operations.hpp</code> in included. However, the generic headers (<code>boost/qvm/mat_operations.hpp</code>, <code>boost/qvm/vec_operations.hpp</code>, <code>boost/qvm/vec_mat_operations.hpp</code> and <code>boost/qvm/swizzle.hpp</code>) already include the generated headers from the list above, so the generated headers don&#8217;t need to be included manually.</p>
6882</div>
6883<div class="admonitionblock note">
6884<table>
6885<tr>
6886<td class="icon">
6887<i class="fa icon-note" title="Note"></i>
6888</td>
6889<td class="content">
6890headers under <code>boost/qvm/gen</code> are not part of the public interface of QVM. For example, <code>boost/qvm/gen/mat_operations2.hpp</code> should not be included directly; <code>#include &lt;boost/qvm/mat_operations2.hpp&gt;</code> instead.
6891</td>
6892</tr>
6893</table>
6894</div>
6895</div>
6896</div>
6897<div class="sect1">
6898<h2 id="_known_quirks_and_issues">Known Quirks and Issues</h2>
6899<div class="sectionbody">
6900<div class="sect2">
6901<h3 id="_capturing_view_proxies_with_auto">Capturing View Proxies with <code>auto</code></h3>
6902<div class="paragraph">
6903<p>By design, <a href="#view_proxy">view proxies</a> must not return temporary objects. They return reference to an argument they take by (<code>const</code>) reference, cast to reference of unspecified type that is not copyable. Because of this, the return value of a view proxy can not be captured by value with <code>auto</code>:</p>
6904</div>
6905<div class="listingblock">
6906<div class="content">
6907<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">auto tr = transposed(m); //Error: the return type of transposed can not be copied.</code></pre>
6908</div>
6909</div>
6910<div class="paragraph">
6911<p>The correct use of auto with view proxies is:</p>
6912</div>
6913<div class="listingblock">
6914<div class="content">
6915<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">auto &amp; tr = transposed(m);</code></pre>
6916</div>
6917</div>
6918<div class="admonitionblock note">
6919<table>
6920<tr>
6921<td class="icon">
6922<i class="fa icon-note" title="Note"></i>
6923</td>
6924<td class="content">
6925Many view proxies are not read-only, that is, they&#8217;re lvalues; changes made on the view proxy operate on the original object. This is another reason why they can not be captured by value with  <code>auto</code>.
6926</td>
6927</tr>
6928</table>
6929</div>
6930<hr>
6931</div>
6932<div class="sect2">
6933<h3 id="_binding_qvm_overloads_from_an_unrelated_namespace">Binding QVM Overloads From an Unrelated Namespace</h3>
6934<div class="paragraph">
6935<p>The operator overloads in namespace <code>boost::qvm</code> are designed to work with user-defined types. Typically it is sufficient to make these operators available in the namespace where the operator is used, by <code>using namespace boost::qvm</code>. A problem arises if the scope that uses the operator is not controlled by the user. For example:</p>
6936</div>
6937<div class="listingblock">
6938<div class="content">
6939<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace ns1 {
6940
6941  struct float2 { float x, y; };
6942
6943}
6944
6945namespace ns2 {
6946
6947  using namespace boost::qvm;
6948
6949  void f() {
6950    ns1::float2 a, b;
6951    a==b; //OK
6952    ns1::float2 arr1[2], arr2[2];
6953    std::equal(arr1,arr1+2,arr2); //Error: operator== is inaccessible from namespace std
6954  }
6955
6956}</code></pre>
6957</div>
6958</div>
6959<div class="paragraph">
6960<p>In the <code>std::equal</code> expression above, even though <code>boost::qvm::operator==</code> is made visible in namespace <code>ns2</code> by <code>using namespace boost::qvm</code>, the call originates from namespace <code>std</code>. In this case the compiler can&#8217;t bind <code>boost::qvm::operator==</code> because only namespace <code>ns1</code> is visible through ADL, and it does not contain a suitable declaration. The solution is to declare <code>operator==</code> in namespace ns1, which can be done like this:</p>
6961</div>
6962<div class="listingblock">
6963<div class="content">
6964<pre class="highlight nowrap"><code class="language-c++" data-lang="c++">namespace ns1 {
6965
6966  using boost::qvm::operator==;
6967
6968}</code></pre>
6969</div>
6970</div>
6971<hr>
6972</div>
6973<div class="sect2">
6974<h3 id="_link_errors_when_calling_math_functions_with_int_arguments">Link Errors When Calling Math Functions with <code>int</code> Arguments</h3>
6975<div class="paragraph">
6976<p>QVM does not call standard math functions (e.g. sin, cos, etc.) directly. Instead, it calls function templates declared in <code>boost/qvm/math.hpp</code> in namespace <code>boost::qvm</code>. This allows the user to specialize these templates for user-defined scalar types.</p>
6977</div>
6978<div class="paragraph">
6979<p>QVM itself defines specializations of the math function templates only for <code>float</code> and <code>double</code>, but it does not provide generic definitions. This is done to protect the user from unintentionally writing code that binds standard math functions that take <code>double</code> when passing arguments of lesser types, which would be suboptimal.</p>
6980</div>
6981<div class="paragraph">
6982<p>Because of this, a call to e.g. <code><a href="#rot_mat">rot_mat</a>(axis,1)</code> will compile successfully but fail to link, since it calls e.g. <code>boost::qvm::sin&lt;int&gt;</code>, which is undefined. Because rotations by integer number of radians are rarely needed, in QVM there is no protection against such errors. In such cases the solution is to use <code>rot_mat(axis,1.0f)</code> instead.</p>
6983</div>
6984</div>
6985</div>
6986</div>
6987<div class="sect1">
6988<h2 id="_distribution">Distribution</h2>
6989<div class="sectionbody">
6990<div class="paragraph">
6991<p>QVM is part of <a href="https://www.boost.org/">Boost</a> and is distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
6992</div>
6993<div class="paragraph">
6994<p>The source code is available in <a href="https://github.com/boostorg/qvm">QVM GitHub repository</a>.</p>
6995</div>
6996<div class="paragraph">
6997<p>&#169; 2008-2018 Emil Dotchevski and Reverge Studios, Inc.</p>
6998</div>
6999</div>
7000</div>
7001<div class="sect1">
7002<h2 id="_portability">Portability</h2>
7003<div class="sectionbody">
7004<div class="paragraph">
7005<p>See the <a href="https://travis-ci.org/boostorg/qvm">QVM Travis CI Builds</a>.</p>
7006</div>
7007</div>
7008</div>
7009<div class="sect1">
7010<h2 id="_feedback_support">Feedback / Support</h2>
7011<div class="sectionbody">
7012<div class="paragraph">
7013<p>Please use the <a href="https://lists.boost.org/mailman/listinfo.cgi/boost">Boost Developers mailing list</a>.</p>
7014</div>
7015</div>
7016</div>
7017<div class="sect1">
7018<h2 id="_qa">Q&amp;A</h2>
7019<div class="sectionbody">
7020<div class="qlist qanda">
7021<ol>
7022<li>
7023<p><em>What is the motivation behind QVM? Why not just use uBLAS/Eigen/CML/GLM/etc?</em></p>
7024<p>The primary domain of QVM is realtime graphics and simulation applications, so it is not a complete linear algebra library. While (naturally) there is some overlap with such libraries, QVM puts the emphasis on 2, 3 and 4 dimensional zero-overhead operations (hence domain-specific features like Swizzling).</p>
7025</li>
7026<li>
7027<p><em>How does the <code>qvm::<a href="#vec">vec</a></code> (or <code>qvm::<a href="#mat">mat</a></code>, or <code>qvm::<a href="#quat">quat</a></code>) template compare to vector types from other libraries?</em></p>
7028<p>The <code>qvm::vec</code> template is not in any way central to the vector operations defined by QVM. The operations are designed to work with any user-defined vector type or with 3rd-party vector types (e.g. <code>D3DVECTOR</code>), while the <code>qvm::vec</code> template is simply a default return type for expressions that use arguments of different types that would be incompatible outside of QVM. For example, if the <a href="#deduce_mat2"><code>deduce_mat2</code></a> hasn&#8217;t been specialized, calling <a href="#cross"><code>cross</code></a> with a user-defined type <code>vec3</code> and a user-defined type <code>float3</code> returns a <code>qvm::vec</code>.</p>
7029</li>
7030<li>
7031<p><em>Why doesn&#8217;t QVM use [] or () to access vector and matrix elements?</em></p>
7032<p>Because it&#8217;s designed to work with user-defined types, and the C&#43;&#43; standard requires these operators to be members. Of course if a user-defined type defines <code>operator[]</code> or <code>operator()</code> they are available for use with other QVM functions, but QVM defines its own mechanisms for <a href="#quat_access">accessing quaternion elements</a>, <a href="#vec_access">accessing vector elements</a> (as well as <a href="#swizzling">swizzling</a>), and <a href="#mat_access">accessing matrix elements</a>.</p>
7033</li>
7034</ol>
7035</div>
7036<hr>
7037<div class="paragraph text-right">
7038<p>Documentation rendered by <a href="https://asciidoctor.org/">Asciidoctor</a> with <a href="https://github.com/zajo/asciidoctor_skin">these customizations</a>.</p>
7039</div>
7040<div class="paragraph text-right">
7041<p>&#169; 2008-2020 Emil Dotchevski and Reverge Studios, Inc.</p>
7042</div>
7043</div>
7044</div>
7045</div>
7046<div id="footer">
7047<div id="footer-text">
7048</div>
7049</div>
7050</body>
7051</html>