
<WARNING! LOT OF LETTERS!> to all on 15.08.2009 at 13:14 joel wrote :
till now i actually don't see any critical flaws in the design implementation will be altered in any way of course Well, the problem is not the design per itself. What usually happens with such lib is that you have tons of different user types that all want disjoint set of features. about tons of user types here is a train of thought (great album by Dream Theater by the way)
(general case) consider there are a matrix_expression class and a matrix class which derives from matrix_expression<matrix<type> > (CRTP) we can now write stuff like matrix<type> m = m1*m2 + m3*a; //a is a scalar then one must think that allocating matrix on the stack is a good idea since such (compile time) decision must be implemented somewhere, why not in a distinct type? no problem! static_matrix<type, 3, 3> m /*= m1*m2 + m3*a*/; //^^here goes size of matrix it derives from matrix_expression<static_matrix<type, 3, 3> > so all operations fall to general case it could actually be 'matrix<type, 3, 3>' but either it is perfectly readable, easy to understand, easy to implement you are welcome... and also one can write void foo(const static_matrix<type, 3, 3> &m); clearly stating that "i really wanna get a 3 by 3 matrix specifically of that type!" of course he (the one) meant 'static_matrix' type "but hey! i also have a symmetric matrix which must be handled a bit special" the one may say again, not a problem lets define 'symmetric_matrix_expression' which derives from matrix_expression we can do this because actually they are connected with 'is-a' relationship, in other words symmetric matrix is a matrix (but not vice versa) so we deliver 'symmetric_matrix' (which derives from symmetric_matrix_expression) and now can optimize some operations: symmetric_matrix<type> m = m1*m2 + m3*a; //m1, m2 & m3 are symmetric now one can clearly state that he void need_symmetric(const symmetric_matrix<type> &m); for a particular operation and if another user write matrix<type> m; //... need_symmetric(m); //need to explicitly turn m to symmetric it won't compile because 'm' is not necessarily symmetric but in an expression m = m1 + symmetric1*symmetric2; operations will fall back to general case isn't it nice? why stopping? then one can define diagonal_matrix_expression which is actually symmetric so it derives from symmetric_matrix_expression bla bla bla... define diagonal_matrix... bla bla bla... (by the way an identity matrix is diagonal) then one can write diagonal_matrix<type> d = identity<type>(v.size()) + diag(v); //v is a vector while symmetric1 - a*identity<type>(N) is still a symmetric expression (and can be handled acordingly) resume: in my opinion this all is convinient, delivers clarity of user code, easy to understand and implement, easy to customize and extend what do you think about it? -- Pavel