]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/qvm/doc/SFINAE_enable_if.html
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / qvm / doc / SFINAE_enable_if.html
1 <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
2 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
3 <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
4 <head>
5 <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
6 <title>SFINAE/enable_if</title>
7 <link href='reno.css' type='text/css' rel='stylesheet'/>
8 </head>
9 <body>
10 <div class="body-0">
11 <div class="body-1">
12 <div class="body-2">
13 <div>
14 <h1>QVM: Quaternions, Vectors, Matrices</h1>
15 </div>
16 <!-- Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc. -->
17 <!-- Distributed under the Boost Software License, Version 1.0. (See accompanying -->
18 <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
19 <div class="RenoIncludeDIV"><div class="RenoAutoDIV"><h3>SFINAE/enable_if</h3>
20 </div>
21 <p>SFINAE stands for Substitution Failure Is Not An Error. This refers to a situation in C++ 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>
22 <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 <span class="RenoLink"><a href="http://www.boost.org/doc/libs/release/libs/utility/enable_if.html">Boost enable_if library</a></span>.</p>
23 <p>For example, Boost QVM defines <i>operator*</i> overload which works with any user-defined matrix and vector types. The naive approach would be to declare this overload as follows:</p>
24 <pre>template &lt;class Matrix,class Vector&gt;
25 Vector operator*( Matrix const &amp; m, Vector const &amp; v );</pre>
26 <p>Even if the function definition might contain code that would compile only for <i>Matrix</i> and <i>Vector</i> 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>
27 <p>Using <i><span class="RenoLink"><a href="enable_if.html">enable_if</a></span></i>, Boost QVM declares such overloads in a way that they retain 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>
28 <pre>template &lt;class A,class B&gt;
29 typename <span class="RenoLink"><a href="enable_if.html">enable_if_c</a></span>&lt;
30 <span class="RenoLink"><a href="is_mat.html">is_mat</a></span>&lt;A&gt;::value &amp;&amp; <span class="RenoLink"><a href="is_vec.html">is_vec</a></span>&lt;B&gt;::value &amp;&amp; <span class="RenoLink"><a href="mat_traits.html">mat_traits</a></span>&lt;A&gt;::<span class="RenoLink"><a href="mat_traits_Matrix_cols.html">cols</a></span>==<span class="RenoLink"><a href="vec_traits.html">vec_traits</a></span>&lt;B&gt;::<span class="RenoLink"><a href="vec_traits_Vector_dim.html">dim</a></span>, //Condition
31 B&gt;::type //Return type
32 operator*( A const &amp; a, B const &amp; b );</pre>
33 <p>For brevity, function declarations throughout this documentation specify the condition which controls whether they are enabled or not without specifying exactly what <i><span class="RenoLink"><a href="enable_if.html">enable_if</a></span></i> construct is used to achieve this effect.</p>
34 </div><div class="RenoAutoDIV"><div class="RenoHR"><hr/></div>
35 See also: <span class="RenoPageList"><a href="accessing_matrix_elements.html">Accessing Matrix Elements</a>&nbsp;| <a href="accessing_quaternion_elements.html">Accessing Quaternion Elements</a>&nbsp;| <a href="accessing_vector_elements.html">Accessing Vector Elements</a>&nbsp;| <a href="assign_mat_mat_.html">assign(mat,mat)</a>&nbsp;| <a href="assign_quat_quat_.html">assign(quat,quat)</a>&nbsp;| <a href="assign_vec_vec_.html">assign(vec,vec)</a>&nbsp;| <a href="index.html">Boost QVM</a>&nbsp;| <a href="boost_qvm_enable_if_hpp.html">boost/qvm/enable_if.hpp</a>&nbsp;| <a href="boost_qvm_swizzle_hpp.html">boost/qvm/swizzle.hpp</a>&nbsp;| <a href="cmp_mat_mat_.html">cmp(mat,mat)</a>&nbsp;| <a href="cmp_quat_quat_.html">cmp(quat,quat)</a>&nbsp;| <a href="cmp_vec_vec_.html">cmp(vec,vec)</a>&nbsp;| <a href="col.html">col</a>&nbsp;| <a href="col_mat.html">col_mat</a>&nbsp;| <a href="conjugate.html">conjugate</a>&nbsp;| <a href="convert_to_mat_.html">convert_to(mat)</a>&nbsp;| <a href="convert_to_quat_.html">convert_to(quat)</a>&nbsp;| <a href="convert_to_vec_.html">convert_to(vec)</a>&nbsp;| <a href="cross.html">cross</a>&nbsp;| <a href="determinant.html">determinant</a>&nbsp;| <a href="diag.html">diag</a>&nbsp;| <a href="diag_mat.html">diag_mat</a>&nbsp;| <a href="dot_quat_quat_.html">dot(quat,quat)</a>&nbsp;| <a href="dot_vec_vec_.html">dot(vec,vec)</a>&nbsp;| <a href="enable_if.html">enable_if</a>&nbsp;| <a href="inverse_mat_.html">inverse(mat)</a>&nbsp;| <a href="inverse_quat_.html">inverse(quat)</a>&nbsp;| <a href="mag_quat_.html">mag(quat)</a>&nbsp;| <a href="mag_vec_.html">mag(vec)</a>&nbsp;| <a href="mag_sqr_quat_.html">mag_sqr(quat)</a>&nbsp;| <a href="mag_sqr_vec_.html">mag_sqr(vec)</a>&nbsp;| <a href="mat_index_read.html">mat_index_read</a>&nbsp;| <a href="mat_index_write.html">mat_index_write</a>&nbsp;| <a href="mref.html">mref</a>&nbsp;| <a href="normalize_quat_.html">normalize(quat)</a>&nbsp;| <a href="normalize_vec_.html">normalize(vec)</a>&nbsp;| <a href="normalized_quat_.html">normalized(quat)</a>&nbsp;| <a href="normalized_vec_.html">normalized(vec)</a>&nbsp;| <a href="operator_not_eq_mat_mat_.html">operator!=(mat,mat)</a>&nbsp;| <a href="operator_not_eq_quat_quat_.html">operator!=(quat,quat)</a>&nbsp;| <a href="operator_not_eq_vec_vec_.html">operator!=(vec,vec)</a>&nbsp;| <a href="operator_times_mat_mat_.html">operator*(mat,mat)</a>&nbsp;| <a href="operator_times_mat_scalar_.html">operator*(mat,scalar)</a>&nbsp;| <a href="operator_times_mat_vec_.html">operator*(mat,vec)</a>&nbsp;| <a href="operator_times_quat_quat_.html">operator*(quat,quat)</a>&nbsp;| <a href="operator_times_quat_scalar_.html">operator*(quat,scalar)</a>&nbsp;| <a href="operator_times_quat_vec_.html">operator*(quat,vec)</a>&nbsp;| <a href="operator_times_vec_mat_.html">operator*(vec,mat)</a>&nbsp;| <a href="operator_times_vec_scalar_.html">operator*(vec,scalar)</a>&nbsp;| <a href="operator_mul_eq_mat_mat_.html">operator*=(mat,mat)</a>&nbsp;| <a href="operator_mul_eq_mat_scalar_.html">operator*=(mat,scalar)</a>&nbsp;| <a href="operator_mul_eq_quat_quat_.html">operator*=(quat,quat)</a>&nbsp;| <a href="operator_mul_eq_quat_scalar_.html">operator*=(quat,scalar)</a>&nbsp;| <a href="operator_mul_eq_vec_scalar_.html">operator*=(vec,scalar)</a>&nbsp;| <a href="operator_plus_mat_mat_.html">operator+(mat,mat)</a>&nbsp;| <a href="operator_plus_quat_quat_.html">operator+(quat,quat)</a>&nbsp;| <a href="operator_plus_vec_vec_.html">operator+(vec,vec)</a>&nbsp;| <a href="operator_add_mat_mat_.html">operator+=(mat,mat)</a>&nbsp;| <a href="operator_add_quat_quat_.html">operator+=(quat,quat)</a>&nbsp;| <a href="operator_add_vec_vec_.html">operator+=(vec,vec)</a>&nbsp;| <a href="operator_minus_mat_.html">operator-(mat)</a>&nbsp;| <a href="operator_minus_mat_mat_.html">operator-(mat,mat)</a>&nbsp;| <a href="operator_minus_quat_.html">operator-(quat)</a>&nbsp;| <a href="operator_minus_quat_quat_.html">operator-(quat,quat)</a>&nbsp;| <a href="operator_minus_vec_.html">operator-(vec)</a>&nbsp;| <a href="operator_minus_vec_vec_.html">operator-(vec,vec)</a>&nbsp;| <a href="operator_sub_eq_mat_mat_.html">operator-=(mat,mat)</a>&nbsp;| <a href="operator_sub_eq_quat_quat_.html">operator-=(quat,quat)</a>&nbsp;| <a href="operator_sub_eq_vec_vec_.html">operator-=(vec,vec)</a>&nbsp;| <a href="operator_over_mat_scalar_.html">operator/(mat,scalar)</a>&nbsp;| <a href="operator_over_quat_scalar_.html">operator/(quat,scalar)</a>&nbsp;| <a href="operator_over_vec_scalar_.html">operator/(vec,scalar)</a>&nbsp;| <a href="operator_div_eq_mat_scalar_.html">operator/=(mat,scalar)</a>&nbsp;| <a href="operator_div_eq_quat_scalar_.html">operator/=(quat,scalar)</a>&nbsp;| <a href="operator_div_eq_vec_scalar_.html">operator/=(vec,scalar)</a>&nbsp;| <a href="operator_eq_mat_mat_.html">operator==(mat,mat)</a>&nbsp;| <a href="operator_eq_quat_quat_.html">operator==(quat,quat)</a>&nbsp;| <a href="operator_eq_vec_vec_.html">operator==(vec,vec)</a>&nbsp;| <a href="qref.html">qref</a>&nbsp;| <a href="qvm.html">qvm</a>&nbsp;| <a href="rot_mat.html">rot_mat</a>&nbsp;| <a href="rot_quat.html">rot_quat</a>&nbsp;| <a href="rotate_mat_vec_scalar_.html">rotate(mat,vec,scalar)</a>&nbsp;| <a href="rotate_quat_vec_scalar_.html">rotate(quat,vec,scalar)</a>&nbsp;| <a href="rotate_x_mat_scalar_.html">rotate_x(mat,scalar)</a>&nbsp;| <a href="rotate_x_quat_scalar_.html">rotate_x(quat,scalar)</a>&nbsp;| <a href="rotate_y_mat_scalar_.html">rotate_y(mat,scalar)</a>&nbsp;| <a href="rotate_y_quat_scalar_.html">rotate_y(quat,scalar)</a>&nbsp;| <a href="rotate_z_mat_scalar_.html">rotate_z(mat,scalar)</a>&nbsp;| <a href="rotate_z_quat_scalar_.html">rotate_z(quat,scalar)</a>&nbsp;| <a href="row.html">row</a>&nbsp;| <a href="row_mat.html">row_mat</a>&nbsp;| <a href="scalar_cast_mat_.html">scalar_cast(mat)</a>&nbsp;| <a href="scalar_cast_quat_.html">scalar_cast(quat)</a>&nbsp;| <a href="scalar_cast_vec_.html">scalar_cast(vec)</a>&nbsp;| <a href="set_identity_mat_.html">set_identity(mat)</a>&nbsp;| <a href="set_identity_quat_.html">set_identity(quat)</a>&nbsp;| <a href="set_rot_mat_vec_scalar_.html">set_rot(mat,vec,scalar)</a>&nbsp;| <a href="set_rot_quat_vec_scalar_.html">set_rot(quat,vec,scalar)</a>&nbsp;| <a href="set_rotx_mat_scalar_.html">set_rotx(mat,scalar)</a>&nbsp;| <a href="set_rotx_quat_scalar_.html">set_rotx(quat,scalar)</a>&nbsp;| <a href="set_roty_mat_scalar_.html">set_roty(mat,scalar)</a>&nbsp;| <a href="set_roty_quat_scalar_.html">set_roty(quat,scalar)</a>&nbsp;| <a href="set_rotz_mat_scalar_.html">set_rotz(mat,scalar)</a>&nbsp;| <a href="set_rotz_quat_scalar_.html">set_rotz(quat,scalar)</a>&nbsp;| <a href="set_zero_mat_.html">set_zero(mat)</a>&nbsp;| <a href="set_zero_quat_.html">set_zero(quat)</a>&nbsp;| <a href="set_zero_vec_.html">set_zero(vec)</a>&nbsp;| <a href="sfinae.html">sfinae</a>&nbsp;| <a href="slerp.html">slerp</a>&nbsp;| <a href="transform_point.html">transform_point</a>&nbsp;| <a href="transform_vector.html">transform_vector</a>&nbsp;| <a href="translation.html">translation</a>&nbsp;| <a href="translation_mat.html">translation_mat</a>&nbsp;| <a href="vec_index_read.html">vec_index_read</a>&nbsp;| <a href="vec_index_write.html">vec_index_write</a>&nbsp;| <a href="vref.html">vref</a></span>
36 </div>
37 <!-- Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc. -->
38 <!-- Distributed under the Boost Software License, Version 1.0. (See accompanying -->
39 <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
40 <div id="footer">
41 <p>
42 <a class="logo" href="http://jigsaw.w3.org/css-validator/check/referer"><img class="logo_pic" src="valid-css.png" alt="Valid CSS" height="31" width="88"/></a>
43 <a class="logo" href="http://validator.w3.org/check?uri=referer"><img class="logo_pic" src="valid-xhtml.png" alt="Valid XHTML 1.0" height="31" width="88"/></a>
44 <small>Copyright (c) 2008-2016 by Emil Dotchevski and Reverge Studios, Inc.<br/>
45 Distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</small>
46 </p>
47 </div>
48 </div>
49 </div>
50 </div>
51 </body>
52 </html>