xref: /aosp_15_r20/external/eigen/doc/TopicAssertions.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li
3*bf2c3715SXin Li/** \page TopicAssertions Assertions
4*bf2c3715SXin Li
5*bf2c3715SXin Li\eigenAutoToc
6*bf2c3715SXin Li
7*bf2c3715SXin Li\section PlainAssert Assertions
8*bf2c3715SXin Li
9*bf2c3715SXin LiThe macro eigen_assert is defined to be \c eigen_plain_assert by default. We use eigen_plain_assert instead of \c assert to work around a known bug for GCC <= 4.3. Basically, eigen_plain_assert \a is \c assert.
10*bf2c3715SXin Li
11*bf2c3715SXin Li\subsection RedefineAssert Redefining assertions
12*bf2c3715SXin Li
13*bf2c3715SXin LiBoth eigen_assert and eigen_plain_assert are defined in Macros.h. Defining eigen_assert indirectly gives you a chance to change its behavior. You can redefine this macro if you want to do something else such as throwing an exception, and fall back to its default behavior with eigen_plain_assert. The code below tells Eigen to throw an std::runtime_error:
14*bf2c3715SXin Li
15*bf2c3715SXin Li\code
16*bf2c3715SXin Li#include <stdexcept>
17*bf2c3715SXin Li#undef eigen_assert
18*bf2c3715SXin Li#define eigen_assert(x) \
19*bf2c3715SXin Li  if (!(x)) { throw (std::runtime_error("Put your message here")); }
20*bf2c3715SXin Li\endcode
21*bf2c3715SXin Li
22*bf2c3715SXin Li\subsection DisableAssert Disabling assertions
23*bf2c3715SXin Li
24*bf2c3715SXin LiAssertions cost run time and can be turned off. You can suppress eigen_assert by defining \c EIGEN_NO_DEBUG \b before including Eigen headers. \c EIGEN_NO_DEBUG is undefined by default unless \c NDEBUG is defined.
25*bf2c3715SXin Li
26*bf2c3715SXin Li\section StaticAssert Static assertions
27*bf2c3715SXin Li
28*bf2c3715SXin LiStatic assertions are not standardized until C++11. However, in the Eigen library, there are many conditions can and should be detectedat compile time. For instance, we use static assertions to prevent the code below from compiling.
29*bf2c3715SXin Li
30*bf2c3715SXin Li\code
31*bf2c3715SXin LiMatrix3d()  + Matrix4d();   // adding matrices of different sizes
32*bf2c3715SXin LiMatrix4cd() * Vector3cd();  // invalid product known at compile time
33*bf2c3715SXin Li\endcode
34*bf2c3715SXin Li
35*bf2c3715SXin LiStatic assertions are defined in StaticAssert.h. If there is native static_assert, we use it. Otherwise, we have implemented an assertion macro that can show a limited range of messages.
36*bf2c3715SXin Li
37*bf2c3715SXin LiOne can easily come up with static assertions without messages, such as:
38*bf2c3715SXin Li
39*bf2c3715SXin Li\code
40*bf2c3715SXin Li#define STATIC_ASSERT(x) \
41*bf2c3715SXin Li  switch(0) { case 0: case x:; }
42*bf2c3715SXin Li\endcode
43*bf2c3715SXin Li
44*bf2c3715SXin LiHowever, the example above obviously cannot tell why the assertion failed. Therefore, we define a \c struct in namespace Eigen::internal to handle available messages.
45*bf2c3715SXin Li
46*bf2c3715SXin Li\code
47*bf2c3715SXin Litemplate<bool condition>
48*bf2c3715SXin Listruct static_assertion {};
49*bf2c3715SXin Li
50*bf2c3715SXin Litemplate<>
51*bf2c3715SXin Listruct static_assertion<true>
52*bf2c3715SXin Li{
53*bf2c3715SXin Li  enum {
54*bf2c3715SXin Li    YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
55*bf2c3715SXin Li    YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
56*bf2c3715SXin Li    // see StaticAssert.h for all enums.
57*bf2c3715SXin Li  };
58*bf2c3715SXin Li};
59*bf2c3715SXin Li\endcode
60*bf2c3715SXin Li
61*bf2c3715SXin LiAnd then, we define EIGEN_STATIC_ASSERT(CONDITION,MSG) to access Eigen::internal::static_assertion<bool(CONDITION)>::MSG. If the condition evaluates into \c false, your compiler displays a lot of messages explaining there is no MSG in static_assert<false>. Nevertheless, this is \a not in what we are interested. As you can see, all members of static_assert<true> are ALL_CAPS_AND_THEY_ARE_SHOUTING.
62*bf2c3715SXin Li
63*bf2c3715SXin Li\warning
64*bf2c3715SXin LiWhen using this macro, MSG should be a member of static_assertion<true>, or the static assertion \b always fails.
65*bf2c3715SXin LiCurrently, it can only be used in function scope.
66*bf2c3715SXin Li
67*bf2c3715SXin Li\subsection DerivedStaticAssert Derived static assertions
68*bf2c3715SXin Li
69*bf2c3715SXin LiThere are other macros derived from EIGEN_STATIC_ASSERT to enhance readability. Their names are self-explanatory.
70*bf2c3715SXin Li
71*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) - passes if \a TYPE is fixed size.
72*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) - passes if \a TYPE is dynamic size.
73*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_LVALUE(Derived) - failes if \a Derived is read-only.
74*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) - passes if \a Derived is an array expression.
75*bf2c3715SXin Li- <b>EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2)</b> - failes if the two expressions are an array one and a matrix one.
76*bf2c3715SXin Li
77*bf2c3715SXin LiBecause Eigen handles both fixed-size and dynamic-size expressions, some conditions cannot be clearly determined at compile time. We classify them into strict assertions and permissive assertions.
78*bf2c3715SXin Li
79*bf2c3715SXin Li\subsubsection StrictAssertions Strict assertions
80*bf2c3715SXin Li
81*bf2c3715SXin LiThese assertions fail if the condition <b>may not</b> be met. For example, MatrixXd may not be a vector, so it fails EIGEN_STATIC_ASSERT_VECTOR_ONLY.
82*bf2c3715SXin Li
83*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) - passes if \a TYPE must be a vector type.
84*bf2c3715SXin Li- <b>EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE)</b> - passes if \a TYPE must be a vector of the given size.
85*bf2c3715SXin Li- <b>EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS)</b> - passes if \a TYPE must be a matrix with given rows and columns.
86*bf2c3715SXin Li
87*bf2c3715SXin Li\subsubsection PermissiveAssertions Permissive assertions
88*bf2c3715SXin Li
89*bf2c3715SXin LiThese assertions fail if the condition \b cannot be met. For example, MatrixXd and Matrix4d may have the same size, so they pass EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE.
90*bf2c3715SXin Li
91*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) - fails if the two vector expression types must have different sizes.
92*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) - fails if the two matrix expression types must have different sizes.
93*bf2c3715SXin Li- \b EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) - fails if \a TYPE cannot be an 1x1 expression.
94*bf2c3715SXin Li
95*bf2c3715SXin LiSee StaticAssert.h for details such as what messages they throw.
96*bf2c3715SXin Li
97*bf2c3715SXin Li\subsection DisableStaticAssert Disabling static assertions
98*bf2c3715SXin Li
99*bf2c3715SXin LiIf \c EIGEN_NO_STATIC_ASSERT is defined, static assertions turn into <tt>eigen_assert</tt>'s, working like:
100*bf2c3715SXin Li
101*bf2c3715SXin Li\code
102*bf2c3715SXin Li#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
103*bf2c3715SXin Li\endcode
104*bf2c3715SXin Li
105*bf2c3715SXin LiThis saves compile time but consumes more run time. \c EIGEN_NO_STATIC_ASSERT is undefined by default.
106*bf2c3715SXin Li
107*bf2c3715SXin Li*/
108*bf2c3715SXin Li}
109