]> Dogcows Code - chaz/yoink/commitdiff
cml version bump to 1.0.1
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sat, 5 Sep 2009 02:17:02 +0000 (20:17 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sat, 5 Sep 2009 02:17:02 +0000 (20:17 -0600)
19 files changed:
src/Moof/cml/constants.h
src/Moof/cml/core/meta/common.h
src/Moof/cml/et/scalar_promotions.h
src/Moof/cml/mathlib/frustum.h
src/Moof/cml/mathlib/matrix_rotation.h
src/Moof/cml/mathlib/matrix_translation.h
src/Moof/cml/mathlib/typedef.h
src/Moof/cml/mathlib/vector_ortho.h
src/Moof/cml/matrix/dynamic.h
src/Moof/cml/matrix/external.h
src/Moof/cml/matrix/fixed.h
src/Moof/cml/matrix/matrix_promotions.h
src/Moof/cml/matrix/matrix_unroller.h
src/Moof/cml/quaternion/quaternion.h
src/Moof/cml/util.h
src/Moof/cml/vector/dynamic.h
src/Moof/cml/vector/external.h
src/Moof/cml/vector/fixed.h
src/Moof/cml/vector/vector_print.h

index 060705c1e3736d81905d026c8d66b300de7d670c..d3392ef8b49798f76f73d2404495abdac685eac1 100644 (file)
@@ -37,19 +37,21 @@ namespace cml {
  */
 template<typename Float>
 struct constants {
-    static Float pi()           { return M_PI;                             }
-    static Float two_pi()       { return 2.*M_PI;                          }
-    static Float inv_pi()       { return 1./M_PI;                          }
-    static Float inv_two_pi()   { return 1./(2.*M_PI);                     }
-    static Float pi_over_2()    { return M_PI/2.;                          }
-    static Float pi_over_4()    { return M_PI/4.;                          }
-    static Float deg_per_rad()  { return 180./M_PI;                        }
-    static Float rad_per_deg()  { return M_PI/180.;                        }
-    static Float sqrt_2()       { return M_SQRT2;                          }
-    static Float sqrt_3()       { return 1.732050807568877293527446341505; }
-    static Float sqrt_5()       { return 2.236067977499789696409173668731; }
-    static Float sqrt_6()       { return 2.449489742783178098197284074705; }
-    static Float e()            { return M_E;                              }
+    static Float pi()          { return Float(M_PI); }
+    static Float two_pi()      { return Float(2.*M_PI); }
+    static Float inv_pi()      { return Float(1./M_PI); }
+    static Float inv_two_pi()  { return Float(1./(2.*M_PI)); }
+    static Float pi_over_2()   { return Float(M_PI/2.); }
+    static Float pi_over_4()   { return Float(M_PI/4.); }
+    static Float deg_per_rad() { return Float(180./M_PI); }
+    static Float rad_per_deg() { return Float(M_PI/180.); }
+
+    static Float sqrt_2() { return Float(M_SQRT2); }
+    static Float sqrt_3() { return Float(1.732050807568877293527446341505); }
+    static Float sqrt_5() { return Float(2.236067977499789696409173668731); }
+    static Float sqrt_6() { return Float(2.449489742783178098197284074705); }
+
+    static Float e() { return Float(M_E); }
 };
 
 #else
index 6d9b8761b439ed689ce5eb5cac3050cf80286cc5..08c129d295985b6f0af051b46fc8ba55e6c7b450 100644 (file)
@@ -80,6 +80,36 @@ template<> struct same_type<any_type,any_type> {
     enum { is_true = true, is_false = false };
 };
 
+/** Remove a reference qualifier from a type. */
+template<typename T> struct remove_reference {
+    template<typename Q, typename Dummy> struct helper {
+        typedef Q type;
+    };
+
+    template<typename Q> struct helper<Q&, void> {
+        typedef Q type;
+    };
+
+    template<typename Q> struct helper<const Q&, void> {
+        typedef const Q type;
+    };
+
+    typedef typename helper<T,void>::type type;
+};
+
+/** Remove a const qualifier from a type. */
+template<typename T> struct remove_const {
+    template<typename Q, typename Dummy> struct helper {
+        typedef Q type;
+    };
+
+    template<typename Q> struct helper<const Q, void> {
+        typedef Q type;
+    };
+
+    typedef typename helper<T,void>::type type;
+};
+
 } // namespace cml
 
 #endif
index 55d033ca5ef52a93053baa679618e5f00f2e8c39..bb6f8a271e7eed965376895a5065d21fda7b7b54 100644 (file)
@@ -13,11 +13,135 @@ Boost Software License, v1.0 (see cml/LICENSE for details).
 #ifndef scalar_promotions_h
 #define scalar_promotions_h
 
+#include <complex>
 #include <cml/core/cml_meta.h>
 
 namespace cml {
 namespace et {
 
+// #define CML_USE_OLD_SCALAR_PROMOTIONS
+#if !defined(CML_USE_OLD_SCALAR_PROMOTIONS)
+
+/* The type promotion code below is a slightly modified version of:
+ * http://ubiety.uwaterloo.ca/~tveldhui/papers/techniques/techniques01.html
+ */
+namespace detail {
+
+template<class T>
+struct precision_trait {
+    enum { precisionRank = 0,
+           knowPrecisionRank = 0 };
+};
+
+#define DECLARE_PRECISION(T,rank)             \
+    template<>                                \
+    struct precision_trait< T > {             \
+        enum { precisionRank = rank,          \
+           knowPrecisionRank = 1 };           \
+    };
+
+DECLARE_PRECISION(int,100)
+DECLARE_PRECISION(unsigned int,200)
+DECLARE_PRECISION(long,300)
+DECLARE_PRECISION(unsigned long,400)
+
+DECLARE_PRECISION(long long,425)
+DECLARE_PRECISION(unsigned long long,475)
+
+DECLARE_PRECISION(float,500)
+DECLARE_PRECISION(double,600)
+DECLARE_PRECISION(long double,700)
+DECLARE_PRECISION(std::complex<float>,800)
+DECLARE_PRECISION(std::complex<double>,900)
+DECLARE_PRECISION(std::complex<long double>,1000)
+
+template<class T>
+struct autopromote_trait {
+    typedef T T_numtype;
+};
+
+#define DECLARE_AUTOPROMOTE(T1,T2)        \
+    template<>                            \
+    struct autopromote_trait<T1> {        \
+      typedef T2 T_numtype;               \
+    };
+
+// These are the odd cases where small integer types
+// are automatically promoted to int or unsigned int for
+// arithmetic.
+DECLARE_AUTOPROMOTE(bool, int)
+DECLARE_AUTOPROMOTE(char, int)
+DECLARE_AUTOPROMOTE(unsigned char, int)
+DECLARE_AUTOPROMOTE(short int, int)
+DECLARE_AUTOPROMOTE(short unsigned int, unsigned int)
+
+template<class T1, class T2, int promoteToT1>
+struct promote2 {
+    typedef T1 T_promote;
+};
+
+template<class T1, class T2>
+struct promote2<T1,T2,0> {
+    typedef T2 T_promote;
+};
+
+template<class T1_orig, class T2_orig>
+struct promote_trait {
+    // Handle promotion of small integers to int/unsigned int
+    typedef typename autopromote_trait<T1_orig>::T_numtype T1;
+    typedef typename autopromote_trait<T2_orig>::T_numtype T2;
+
+    // True if T1 is higher ranked
+    enum {
+      T1IsBetter =
+        (int) precision_trait<T1>::precisionRank >
+          (int) precision_trait<T2>::precisionRank,
+
+    // True if we know ranks for both T1 and T2
+      knowBothRanks =
+        precision_trait<T1>::knowPrecisionRank
+      && precision_trait<T2>::knowPrecisionRank,
+
+    // True if we know T1 but not T2
+      knowT1butNotT2 =  precision_trait<T1>::knowPrecisionRank
+        && !(precision_trait<T2>::knowPrecisionRank),
+
+    // True if we know T2 but not T1
+      knowT2butNotT1 =  precision_trait<T2>::knowPrecisionRank
+        && !(precision_trait<T1>::knowPrecisionRank),
+
+    // True if T1 is bigger than T2
+      T1IsLarger = sizeof(T1) >= sizeof(T2),
+
+    // We know T1 but not T2: true
+    // We know T2 but not T1: false
+    // Otherwise, if T1 is bigger than T2: true
+      defaultPromotion = knowT1butNotT2 ? false :
+         (knowT2butNotT1 ? true : T1IsLarger)
+    };
+
+    // If we have both ranks, then use them.
+    // If we have only one rank, then use the unknown type.
+    // If we have neither rank, then promote to the larger type.
+
+    enum {
+      promoteToT1 = (knowBothRanks ? T1IsBetter : defaultPromotion) 
+                        ? 1 : 0
+    };
+
+    typedef typename promote2<T1,T2,promoteToT1>::T_promote T_promote;
+};
+
+} // namespace detail
+
+/** Defers to detail::promote_trait<>. */
+template<class E1, class E2> struct ScalarPromote
+{
+    typedef typename detail::promote_trait<E1,E2>::T_promote type;
+};
+
+#else
+
 namespace detail {
 
 /** @class IntPromote
@@ -43,7 +167,6 @@ template<class T> struct IntPromote
  */
 template<class E1_in, class E2_in> struct ScalarPromote
 {
-
     /* Integral-promote the types (if possible). */
     typedef typename detail::IntPromote<E1_in>::result  E1;
     typedef typename detail::IntPromote<E2_in>::result  E2;
@@ -110,6 +233,7 @@ template<class E1_in, class E2_in> struct ScalarPromote
         same_type<float_filter,void>::is_true,
         int_filter, float_filter>::result         type;
 };
+#endif
 
 } // namespace et
 } // namespace cml
index 6a707afb78dc2019ba8fa44b7bccb02c226841b7..43eb41f8aea876df7fb31a8cc52412b73e834d3a 100644 (file)
@@ -108,18 +108,7 @@ extract_frustum_planes(
     planes[5][3] = m.basis_element(3,3) - m.basis_element(3,2);
     
     /* Near:   [03+02, 13+12, 23+22, 33+32] : [02, 12, 22, 32] */
-    
-    if (z_clip == z_clip_neg_one) {       
-        planes[4][0] = m.basis_element(0,3) + m.basis_element(0,2);
-        planes[4][1] = m.basis_element(1,3) + m.basis_element(1,2);
-        planes[4][2] = m.basis_element(2,3) + m.basis_element(2,2);  
-        planes[4][3] = m.basis_element(3,3) + m.basis_element(3,2);
-    } else { // z_clip == z_clip_zero
-        planes[4][0] = m.basis_element(0,2);
-        planes[4][1] = m.basis_element(1,2);
-        planes[4][2] = m.basis_element(2,2);  
-        planes[4][3] = m.basis_element(3,2);
-    }
+    extract_near_frustum_plane(m, planes[4], z_clip);
 
     /* @todo: This will be handled by the plane class */
     if (normalize) {
@@ -136,6 +125,36 @@ extract_frustum_planes(
     }
 }
 
+/** Extract the near plane of a frustum given a concatenated modelview and
+ * projection matrix with the given near z-clipping range. The plane is
+ * not normalized.
+ *
+ * @note The plane is in ax+by+cz+d = 0 form.
+ *
+ * @warning The matrix is assumed to be a homogeneous transformation
+ * matrix.
+ */
+template < class MatT, class PlaneT > void
+extract_near_frustum_plane(
+    const MatT& m,
+    PlaneT& plane,
+    ZClip z_clip
+    )
+{
+    /* Near:   [03+02, 13+12, 23+22, 33+32] : [02, 12, 22, 32] */
+    if (z_clip == z_clip_neg_one) {       
+        plane[0] = m.basis_element(0,3) + m.basis_element(0,2);
+        plane[1] = m.basis_element(1,3) + m.basis_element(1,2);
+        plane[2] = m.basis_element(2,3) + m.basis_element(2,2);  
+        plane[3] = m.basis_element(3,3) + m.basis_element(3,2);
+    } else { // z_clip == z_clip_zero
+        plane[0] = m.basis_element(0,2);
+        plane[1] = m.basis_element(1,2);
+        plane[2] = m.basis_element(2,2);  
+        plane[3] = m.basis_element(3,2);
+    }
+}
+
 namespace detail {
 
 /* This is currently only in support of finding the corners of a frustum.
index 9c3821d47be051be9c25b294852ba6c0725f656d..2298c224eefad0c9271456c432b0acfb86077be2 100644 (file)
@@ -186,8 +186,11 @@ matrix_rotation_quaternion(matrix<E,A,B,L>& m, const QuatT& q)
  * euler_order_zyx
  * euler_order_zxz
  * euler_order_zyz
+ *
+ * e.g. euler_order_xyz means compute the column-basis rotation matrix
+ * equivalent to R_x * R_y * R_z, where R_i is the rotation matrix above
+ * axis i (the row-basis matrix would be R_z * R_y * R_x).
  */
-
 template < typename E, class A, class B, class L > void
 matrix_rotation_euler(matrix<E,A,B,L>& m, E angle_0, E angle_1, E angle_2,
     EulerOrder order)
@@ -245,6 +248,98 @@ matrix_rotation_euler(matrix<E,A,B,L>& m, E angle_0, E angle_1, E angle_2,
     }
 }
 
+/** Build a matrix of derivatives of Euler angles about the specified axis.
+ *
+ * The rotation derivatives are applied about the cardinal axes in the
+ * order specified by the 'order' argument, where 'order' is one of the
+ * following enumerants:
+ *
+ * euler_order_xyz
+ * euler_order_xzy
+ * euler_order_yzx
+ * euler_order_yxz
+ * euler_order_zxy
+ * euler_order_zyx
+ *
+ * e.g. euler_order_xyz means compute the column-basis rotation matrix
+ * equivalent to R_x * R_y * R_z, where R_i is the rotation matrix above
+ * axis i (the row-basis matrix would be R_z * R_y * R_x).
+ *
+ * The derivative is taken with respect to the specified 'axis', which is
+ * the position of the axis in the triple; e.g. if order = euler_order_xyz,
+ * then axis = 0 would mean take the derivative with respect to x.  Note
+ * that repeated axes are not currently supported.
+ */
+template < typename E, class A, class B, class L > void
+matrix_rotation_euler_derivatives(
+    matrix<E,A,B,L>& m, int axis, E angle_0, E angle_1, E angle_2,
+    EulerOrder order)
+{
+    typedef matrix<E,A,B,L> matrix_type;
+    typedef typename matrix_type::value_type value_type;
+
+    /* Checking */
+    detail::CheckMatLinear3D(m);
+
+    identity_transform(m);
+    
+    size_t i, j, k;
+    bool odd, repeat;
+    detail::unpack_euler_order(order, i, j, k, odd, repeat);
+    if(repeat) throw std::invalid_argument(
+       "matrix_rotation_euler_derivatives does not support repeated axes");
+
+    if (odd) {
+        angle_0 = -angle_0;
+        angle_1 = -angle_1;
+        angle_2 = -angle_2;
+    }
+
+    value_type s0 = std::sin(angle_0);
+    value_type c0 = std::cos(angle_0);
+    value_type s1 = std::sin(angle_1);
+    value_type c1 = std::cos(angle_1);
+    value_type s2 = std::sin(angle_2);
+    value_type c2 = std::cos(angle_2);
+    
+    value_type s0s2 = s0 * s2;
+    value_type s0c2 = s0 * c2;
+    value_type c0s2 = c0 * s2;
+    value_type c0c2 = c0 * c2;
+
+    if(axis == 0) {
+      m.set_basis_element(i,i, 0.              );
+      m.set_basis_element(i,j, 0.              );
+      m.set_basis_element(i,k, 0.              );
+      m.set_basis_element(j,i, s1 * c0*c2 + s0*s2);
+      m.set_basis_element(j,j, s1 * c0*s2 - s0*c2);
+      m.set_basis_element(j,k, c0 * c1         );
+      m.set_basis_element(k,i,-s1 * s0*c2 + c0*s2);
+      m.set_basis_element(k,j,-s1 * s0*s2 - c0*c2);
+      m.set_basis_element(k,k,-s0 * c1         );
+    } else if(axis == 1) {
+      m.set_basis_element(i,i,-s1 * c2         );
+      m.set_basis_element(i,j,-s1 * s2         );
+      m.set_basis_element(i,k,-c1              );
+      m.set_basis_element(j,i, c1 * s0*c2      );
+      m.set_basis_element(j,j, c1 * s0*s2      );
+      m.set_basis_element(j,k,-s0 * s1         );
+      m.set_basis_element(k,i, c1 * c0*c2      );
+      m.set_basis_element(k,j, c1 * c0*s2      );
+      m.set_basis_element(k,k,-c0 * s1         );
+    } else if(axis == 2) {
+      m.set_basis_element(i,i,-c1 * s2         );
+      m.set_basis_element(i,j, c1 * c2         );
+      m.set_basis_element(i,k, 0.              );
+      m.set_basis_element(j,i,-s1 * s0*s2 - c0*c2);
+      m.set_basis_element(j,j, s1 * s0*c2 - c0*s2);
+      m.set_basis_element(j,k, 0.              );
+      m.set_basis_element(k,i,-s1 * c0*s2 + s0*c2);
+      m.set_basis_element(k,j, s1 * c0*c2 + s0*s2);
+      m.set_basis_element(k,k, 0.              );
+    }
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // 3D rotation to align with a vector, multiple vectors, or the view plane
 //////////////////////////////////////////////////////////////////////////////
index dadf4c53c0bcf66f7784aa75bec6c6fe3663c0e5..664c5778da27d18b6a2d6419c17b964ba61902f3 100644 (file)
@@ -104,6 +104,26 @@ matrix_get_translation(const MatT& m)
     );
 }
 
+/** Get the translation of a 3D affine transform */
+template < class MatT > void
+matrix_get_translation(
+    const MatT& m,
+    typename MatT::value_type& t1,
+    typename MatT::value_type& t2,
+    typename MatT::value_type& t3
+    )
+{
+    typedef typename MatT::value_type value_type;
+    typedef vector< value_type, fixed<3> > vector_type;
+
+    /* Checking */
+    detail::CheckMatAffine3D(m);
+    
+    t1 = m.basis_element(3,0);
+    t2 = m.basis_element(3,1);
+    t3 = m.basis_element(3,2);
+}
+
 /** Get the translation of a 2D affine transform */
 template < class MatT > vector< typename MatT::value_type, fixed<2> >
 matrix_get_translation_2D(const MatT& m)
@@ -117,6 +137,24 @@ matrix_get_translation_2D(const MatT& m)
     return vector_type(m.basis_element(2,0), m.basis_element(2,1));
 }
 
+/** Get the translation of a 2D affine transform */
+template < class MatT > void
+matrix_get_translation_2D(
+    const MatT& m,
+    typename MatT::value_type& t1,
+    typename MatT::value_type& t2
+    )
+{
+    typedef typename MatT::value_type value_type;
+    typedef vector< value_type, fixed<2> > vector_type;
+
+    /* Checking */
+    detail::CheckMatAffine2D(m);
+    
+    t1 = m.basis_element(2,0);
+    t2 = m.basis_element(2,1);
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // Function for getting the translation of a 3D view matrix
 //////////////////////////////////////////////////////////////////////////////
index f34843efb2d0049afbd92de2b884d25956ea308a..902a331d5e2195ff25cca2681ffce994c3643c3f 100644 (file)
@@ -35,6 +35,11 @@ typedef vector< float,  fixed<4> > vector4f;
 typedef vector< double, fixed<4> > vector4d;
 
 /* fixed-size matrices */
+
+typedef matrix< int,    fixed<2,2> > matrix22i;
+typedef matrix< float,  fixed<2,2> > matrix22f;
+typedef matrix< double, fixed<2,2> > matrix22d;
+
 typedef matrix< int,    fixed<2,2>, row_basis, row_major > matrix22i_r;
 typedef matrix< int,    fixed<2,2>, col_basis, col_major > matrix22i_c;
 typedef matrix< float,  fixed<2,2>, row_basis, row_major > matrix22f_r;
@@ -42,6 +47,11 @@ typedef matrix< float,  fixed<2,2>, col_basis, col_major > matrix22f_c;
 typedef matrix< double, fixed<2,2>, row_basis, row_major > matrix22d_r;
 typedef matrix< double, fixed<2,2>, col_basis, col_major > matrix22d_c;
 
+
+typedef matrix< int,    fixed<3,3> > matrix33i;
+typedef matrix< float,  fixed<3,3> > matrix33f;
+typedef matrix< double, fixed<3,3> > matrix33d;
+
 typedef matrix< int,    fixed<3,3>, row_basis, row_major > matrix33i_r;
 typedef matrix< int,    fixed<3,3>, col_basis, col_major > matrix33i_c;
 typedef matrix< float,  fixed<3,3>, row_basis, row_major > matrix33f_r;
@@ -49,6 +59,11 @@ typedef matrix< float,  fixed<3,3>, col_basis, col_major > matrix33f_c;
 typedef matrix< double, fixed<3,3>, row_basis, row_major > matrix33d_r;
 typedef matrix< double, fixed<3,3>, col_basis, col_major > matrix33d_c;
 
+
+typedef matrix< int,    fixed<4,4> > matrix44i;
+typedef matrix< float,  fixed<4,4> > matrix44f;
+typedef matrix< double, fixed<4,4> > matrix44d;
+
 typedef matrix< int,    fixed<4,4>, row_basis, row_major > matrix44i_r;
 typedef matrix< int,    fixed<4,4>, col_basis, col_major > matrix44i_c;
 typedef matrix< float,  fixed<4,4>, row_basis, row_major > matrix44f_r;
@@ -56,6 +71,7 @@ typedef matrix< float,  fixed<4,4>, col_basis, col_major > matrix44f_c;
 typedef matrix< double, fixed<4,4>, row_basis, row_major > matrix44d_r;
 typedef matrix< double, fixed<4,4>, col_basis, col_major > matrix44d_c;
 
+
 typedef matrix< int,    fixed<3,2>, row_basis, row_major > matrix32i_r;
 typedef matrix< float,  fixed<3,2>, row_basis, row_major > matrix32f_r;
 typedef matrix< double, fixed<3,2>, row_basis, row_major > matrix32d_r;
@@ -72,6 +88,7 @@ typedef matrix< int,    fixed<3,4>, col_basis, col_major > matrix34i_c;
 typedef matrix< float,  fixed<3,4>, col_basis, col_major > matrix34f_c;
 typedef matrix< double, fixed<3,4>, col_basis, col_major > matrix34d_c;
 
+
 /* quaternions */
 typedef quaternion<float, fixed<>,vector_first,negative_cross>
     quaternionf_n;
@@ -81,13 +98,21 @@ typedef quaternion<double,fixed<>,vector_first,negative_cross>
     quaterniond_n;
 typedef quaternion<double,fixed<>,vector_first,positive_cross>
     quaterniond_p;
+typedef quaternion<float> quaternionf;
+typedef quaternion<double> quaterniond;
+
 
 /* dynamically resizable vectors */
 typedef vector< int,    dynamic<> > vectori;
 typedef vector< float,  dynamic<> > vectorf;
 typedef vector< double, dynamic<> > vectord;
 
+
 /* dynamically resizable matrices */
+typedef matrix< int,    dynamic<> > matrixi;
+typedef matrix< float,  dynamic<> > matrixf;
+typedef matrix< double, dynamic<> > matrixd;
+
 typedef matrix< int,    dynamic<>, row_basis, row_major > matrixi_r;
 typedef matrix< int,    dynamic<>, col_basis, col_major > matrixi_c;
 typedef matrix< float,  dynamic<>, row_basis, row_major > matrixf_r;
@@ -95,6 +120,7 @@ typedef matrix< float,  dynamic<>, col_basis, col_major > matrixf_c;
 typedef matrix< double, dynamic<>, row_basis, row_major > matrixd_r;
 typedef matrix< double, dynamic<>, col_basis, col_major > matrixd_c;
 
+
 /* constants */
 typedef constants<float>  constantsf;
 typedef constants<double> constantsd;
index 88506f5a0fbe05565c1fe741c202af27e9847f5d..3983264d5e8117da20b79e6ad4662b8d72ede711 100644 (file)
@@ -7,7 +7,9 @@ Boost Software License, v1.0 (see cml/LICENSE for details).
 
  *-----------------------------------------------------------------------*/
 /** @file
- *  @brief
+ *
+ * Functions for orthonormalizing a set of basis vectors in 3D or 2D, and for
+ * constructing an orthonormal basis given various input parameters.
  */
 
 #ifndef vector_ortho_h
@@ -16,13 +18,14 @@ Boost Software License, v1.0 (see cml/LICENSE for details).
 #include <cml/mathlib/vector_misc.h>
 #include <cml/mathlib/misc.h>
 
-/* Functions for orthonormalizing a set of basis vector in 3D or 2D, and for
- * constructing an orthonormal basis given various input parameters.
- */
-
 namespace cml {
 
-/* Orthonormalize 3 basis vectors in R3.
+//////////////////////////////////////////////////////////////////////////////
+// Orthonormalization in 3D and 2D
+//////////////////////////////////////////////////////////////////////////////
+
+
+/** Orthonormalize 3 basis vectors in R3.
  *
  * Called with the default values, this function performs a single Gram-
  * Schmidt step to orthonormalize the input vectors. By default, the direction
@@ -36,11 +39,6 @@ namespace cml {
  * In most cases, the default arguments can be ignored, leaving only the three
  * input vectors.
  */
-
-//////////////////////////////////////////////////////////////////////////////
-// Orthonormalization in 3D and 2D
-//////////////////////////////////////////////////////////////////////////////
-
 template < typename E, class A > void
 orthonormalize(vector<E,A>& v0, vector<E,A>& v1, vector<E,A>& v2,
     size_t stable_axis = 2, size_t num_iter = 0, E s = E(1))
@@ -92,7 +90,7 @@ orthonormalize(vector<E,A>& v0, vector<E,A>& v1, vector<E,A>& v2,
     v2 = v[2];
 }
 
-/* Orthonormalize 2 basis vectors in R2 */
+/** Orthonormalize 2 basis vectors in R2 */
 template < typename E, class A > void
 orthonormalize(vector<E,A>& v0, vector<E,A>& v1,
     size_t stable_axis = 0, size_t num_iter = 0, E s = E(1))
@@ -138,27 +136,25 @@ orthonormalize(vector<E,A>& v0, vector<E,A>& v1,
 // Orthonormal basis construction in 3D and 2D
 //////////////////////////////////////////////////////////////////////////////
 
-/* This version of orthonormal_basis() ultimately does the work for all
+/** This version of orthonormal_basis() ultimately does the work for all
  * orthonormal_basis_*() functions. Given input vectors 'align' and
- * 'reference', and an order 'axis_order_<i><j><k>', it constructs an
+ * 'reference', and an order 'axis_order_\<i\>\<j\>\<k\>', it constructs an
  * orthonormal basis such that the i'th basis vector is aligned with (parallel
  * to and pointing in the same direction as) 'align', and the j'th basis
  * vector is maximally aligned with 'reference'. The k'th basis vector is
  * chosen such that the basis has a determinant of +1.
  *
- * Note that the algorithm fails when 'align' is nearly parallel to
+ * @note The algorithm fails when 'align' is nearly parallel to
  * 'reference'; this should be checked for and handled externally if it's a
  * case that may occur.
- */
-
-/* Note: This is an example of the 'non-const argument modification
+ *
+ * @internal This is an example of the 'non-const argument modification
  * invalidates expression' gotcha. If x, y or z were to be assigned to before
  * we were 'done' with align and reference, and if one of them were the same
  * object as align or reference, then the algorithm could fail. As is the
  * basis vectors are assigned at the end of the function from a temporary
  * array, so all is well.
  */
-
 template < class VecT_1, class VecT_2, typename E, class A > void
 orthonormal_basis(
     const VecT_1& align,
@@ -193,7 +189,7 @@ orthonormal_basis(
     z = axis[2];
 }
 
-/* This version of orthonormal_basis() constructs in arbitrary basis given a
+/** This version of orthonormal_basis() constructs in arbitrary basis given a
  * vector with which to align the i'th basis vector. To avoid the failure
  * case, the reference vector is always chosen so as to not be parallel to
  * 'align'. This means the algorithm will always generate a valid basis, which
@@ -201,7 +197,6 @@ orthonormal_basis(
  * basis will likely 'pop' as the alignment vector changes, and so may not be
  * suitable for billboarding or other similar applications.
  */
-
 template < class VecT, typename E, class A >
 void orthonormal_basis(
     const VecT& align,
@@ -223,7 +218,7 @@ void orthonormal_basis(
     );
 }
 
-/* orthonormal_basis_axial() generates a basis in which the j'th basis vector
+/** orthonormal_basis_axial() generates a basis in which the j'th basis vector
  * is aligned with 'axis' and the i'th basis vector is maximally aligned (as
  * 'aligned as possible') with 'align'. This can be used for e.g. axial
  * billboarding for, say, trees or beam effects.
@@ -232,11 +227,10 @@ void orthonormal_basis(
  * of orthonormal_basis(), with the parameters adjusted so that the alignment
  * is axial.
  *
- * With this algorithm the failure case is when 'align' and 'axis' are nearly
- * parallel; if this is likely, it should be checked for and handled
- * externally.
+ * @note With this algorithm the failure case is when 'align' and 'axis'
+ * are nearly parallel; if this is likely, it should be checked for and
+ * handled externally.
  */
-
 template < class VecT_1, class VecT_2, typename E, class A >
 void orthonormal_basis_axial(
     const VecT_1& align,
@@ -257,11 +251,11 @@ void orthonormal_basis_axial(
         detail::swap_axis_order(order));
 }
 
-/* orthonormal_basis_viewplane() builds a basis aligned with a viewplane, as
+/** orthonormal_basis_viewplane() builds a basis aligned with a viewplane, as
  * extracted from the input view matrix. The function takes into account the
  * handedness of the input view matrix and orients the basis accordingly.
  *
- * The generated basis will always be valid.
+ * @note The generated basis will always be valid.
  */
 template < class MatT, typename E, class A >
 void orthonormal_basis_viewplane(
@@ -309,7 +303,7 @@ void orthonormal_basis_viewplane_RH(
         view_matrix,x,y,z,right_handed,order);
 }
 
-/* Build a 2D orthonormal basis. */
+/** Build a 2D orthonormal basis. */
 template < class VecT, typename E, class A >
 void orthonormal_basis_2D(
     const VecT& align,
index 1362210fa7272009468e8fbfd947122ed7a2df7d..4092bfefaeb5f7b4d7d54f3a764c177a9a43f973 100644 (file)
@@ -205,6 +205,16 @@ class matrix<Element,dynamic<Alloc>,BasisOrient,Layout>
         set_basis_element(i,j,s,basis_orient());
     }
 
+    /** Set the matrix row from the given vector. */
+    void set_row(size_t i, const row_vector_type& row) {
+      for(size_t j = 0; j < this->cols(); ++ j) (*this)(i,j) = row[j];
+    }
+
+    /** Set the matrix column from the given vector. */
+    void set_col(size_t j, const col_vector_type& col) {
+      for(size_t i = 0; i < this->rows(); ++ i) (*this)(i,j) = col[i];
+    }
+
 
   public:
 
index 36c225a067b84cdf4dc4b1533f501c398f59f820..1af926627344d107e4095b7ea805a8ba8bcd99d6 100644 (file)
@@ -221,6 +221,16 @@ class matrix<Element,external<Rows,Cols>,BasisOrient,Layout>
         set_basis_element(i,j,s,basis_orient());
     }
 
+    /** Set the matrix row from the given vector. */
+    void set_row(size_t i, const row_vector_type& row) {
+      for(size_t j = 0; j < this->cols(); ++ j) (*this)(i,j) = row[j];
+    }
+
+    /** Set the matrix column from the given vector. */
+    void set_col(size_t j, const col_vector_type& col) {
+      for(size_t i = 0; i < this->rows(); ++ i) (*this)(i,j) = col[i];
+    }
+
 
   public:
 
@@ -440,6 +450,8 @@ class matrix<Element,external<-1,-1>,BasisOrient,Layout>
      * responsible for doing any necessary memory management.
      *
      * @param ptr specify the external pointer.
+     * @param rows the number of rows in the C array.
+     * @param cols the number of columns in the C array.
      *
      * @throws same as the ArrayType constructor.
      */
index d20ccfaba4841b7259c5a2a17fde2530e92a5faa..f35bf1c64a4f5081ec74e76849cd63aa7cd468b3 100644 (file)
@@ -198,6 +198,16 @@ class matrix<Element,fixed<Rows,Cols>,BasisOrient,Layout>
         set_basis_element(i,j,s,basis_orient());
     }
 
+    /** Set the matrix row from the given vector. */
+    void set_row(size_t i, const row_vector_type& row) {
+      for(size_t j = 0; j < this->cols(); ++ j) (*this)(i,j) = row[j];
+    }
+
+    /** Set the matrix column from the given vector. */
+    void set_col(size_t j, const col_vector_type& col) {
+      for(size_t i = 0; i < this->rows(); ++ i) (*this)(i,j) = col[i];
+    }
+
 
   public:
 
index 18e94bb2509cea057445c4081cf1100817e94013..8be57cb651af62a863f434f34b1627e5abbf5d21 100644 (file)
@@ -33,34 +33,102 @@ struct outer_promote_expects_properly_oriented_args_error;
 namespace cml {
 namespace et {
 
-/* Default matrix type promotion template. */
-template<typename LeftT, typename RightT> struct MatrixPromote;
-
-/** Type promotion for two matrix types.
- *
- * @note This always uses the basis orientation of the left-hand matrix.
- * @bug This always uses the basis orientation of the left-hand matrix,
- *      which is not always correct.
- */
-template<typename E1, class AT1, typename L1, typename BO1,
-         typename E2, class AT2, typename L2, typename BO2>
-struct MatrixPromote< cml::matrix<E1,AT1,BO1,L1>, cml::matrix<E2,AT2,BO2,L2> >
+/** Promote two types to a matrixt type. */
+template<typename LeftT, typename RightT> struct MatrixPromote
 {
-    /* Promote the arrays: */
-    typedef typename ArrayPromote<
-        typename cml::matrix<E1,AT1,BO1,L1>::array_type,
+    /* Default matrix type promotion template. */
+    template<typename M1, typename M2> struct MatrixPromoteHelper;
+
+    /** Type promotion for two matrix types.
+     *
+     * @note This always uses the basis orientation of the left-hand matrix.
+     * @bug This always uses the basis orientation of the left-hand matrix,
+     *      which is not always correct.
+     */
+    template<typename E1, class AT1, typename L1, typename BO1,
+             typename E2, class AT2, typename L2, typename BO2>
+    struct MatrixPromoteHelper<
+    cml::matrix<E1,AT1,BO1,L1>, cml::matrix<E2,AT2,BO2,L2>
+    >
+    {
+        /* Promote the arrays: */
+        typedef typename ArrayPromote<
+            typename cml::matrix<E1,AT1,BO1,L1>::array_type,
         typename cml::matrix<E2,AT2,BO2,L2>::array_type
-    >::type promoted_array;
+            >::type promoted_array;
+
+        /* The deduced matrix result type: */
+        typedef cml::matrix<
+            typename promoted_array::value_type,
+                     typename promoted_array::generator_type,
+                     BO1,
+                     typename promoted_array::layout
+                         > type;
+
+        /* The deduced temporary type: */
+        typedef typename type::temporary_type temporary_type;
+    };
+
+    /** Type promotion for a matrix and a scalar. */
+    template<typename E, class AT, typename BO, typename L, typename S>
+    struct MatrixPromoteHelper<cml::matrix<E,AT,BO,L>, S>
+    {
+        /* The deduced matrix result type (the array type is the same): */
+        typedef cml::matrix<typename ScalarPromote<E,S>::type, AT, BO, L> type;
+
+        /* The deduced temporary type: */
+        typedef typename type::temporary_type temporary_type;
+    };
+
+    /** Type promotion for a scalar and a matrix. */
+    template<typename S, typename E, class AT, typename BO, typename L>
+    struct MatrixPromoteHelper<S, cml::matrix<E,AT,BO,L> >
+    {
+        /* The deduced matrix result type (the array type is the same): */
+        typedef cml::matrix<typename ScalarPromote<S,E>::type, AT, BO, L> type;
 
-    /* The deduced matrix result type: */
-    typedef cml::matrix<
-        typename promoted_array::value_type,
-        typename promoted_array::generator_type,
-        BO1,
-        typename promoted_array::layout
-    > type;
+        /* The deduced temporary type: */
+        typedef typename type::temporary_type temporary_type;
+    };
+
+    /** Type promotion for outer product. */
+    template<typename E1, class AT1, typename E2, class AT2>
+    struct MatrixPromoteHelper< cml::vector<E1,AT1>, cml::vector<E2,AT2> >
+    {
+        typedef cml::vector<E1,AT1> left_type;
+        typedef cml::vector<E2,AT2> right_type;
+        typedef CML_DEFAULT_BASIS_ORIENTATION basis_orient;
+
+        /* Get matrix size: */
+        enum {
+            array_rows = left_type::array_size,
+            array_cols = right_type::array_size
+        };
+
+        /* Deduce the corresponding matrix types for the vectors: */
+        typedef CML_DEFAULT_ARRAY_LAYOUT layout;
+        typedef typename select_if<
+            array_rows == -1, dynamic<>, fixed<array_rows,1>
+            >::result left_storage;
+        typedef cml::matrix<E1,left_storage,basis_orient,layout> left_matrix;
+
+        typedef typename select_if<
+            array_cols == -1, dynamic<>, fixed<1,array_cols>
+            >::result right_storage;
+        typedef cml::matrix<E2,right_storage,basis_orient,layout> right_matrix;
+
+        /* Finally, promote the matrix types to get the result: */
+        typedef typename et::MatrixPromote<left_matrix,right_matrix>::type type;
+        typedef typename type::temporary_type temporary_type;
+    };
+
+    /** Remove const and & from the to-be-promoted types. */
+    typedef typename remove_const<
+        typename remove_reference<LeftT>::type>::type LeftBaseT;
+    typedef typename remove_const<
+        typename remove_reference<RightT>::type>::type RightBaseT;
 
-    /* The deduced temporary type: */
+    typedef typename MatrixPromoteHelper<LeftBaseT,RightBaseT>::type type;
     typedef typename type::temporary_type temporary_type;
 };
 
@@ -75,7 +143,7 @@ struct MatrixPromote2
 {
     typedef typename MatrixPromote<
         typename Mat1_T::temporary_type, typename Mat2_T::temporary_type
-    >::temporary_type temporary_type;
+        >::temporary_type temporary_type;
     typedef typename temporary_type::value_type value_type;
 };
 
@@ -86,9 +154,10 @@ struct MatrixPromote3
     typedef typename MatrixPromote<
         typename Mat1_T::temporary_type,
         typename MatrixPromote<
-            typename Mat2_T::temporary_type, typename Mat3_T::temporary_type
+            typename Mat2_T::temporary_type,
+            typename Mat3_T::temporary_type
         >::temporary_type
-    >::temporary_type temporary_type;
+     >::temporary_type temporary_type;
     typedef typename temporary_type::value_type value_type;
 };
 
@@ -104,64 +173,11 @@ struct MatrixPromote4
                 typename Mat3_T::temporary_type,
                 typename Mat4_T::temporary_type
             >::temporary_type
-        >::temporary_type
-    >::temporary_type temporary_type;
+         >::temporary_type
+     >::temporary_type temporary_type;
     typedef typename temporary_type::value_type value_type;
 };
 
-/** Type promotion for a matrix and a scalar. */
-template<typename E, class AT, typename BO, typename L, typename S>
-struct MatrixPromote<cml::matrix<E,AT,BO,L>, S>
-{
-    /* The deduced matrix result type (the array type is the same): */
-    typedef cml::matrix<typename ScalarPromote<E,S>::type, AT, BO, L> type;
-
-    /* The deduced temporary type: */
-    typedef typename type::temporary_type temporary_type;
-};
-
-/** Type promotion for a scalar and a matrix. */
-template<typename S, typename E, class AT, typename BO, typename L>
-struct MatrixPromote<S, cml::matrix<E,AT,BO,L> >
-{
-    /* The deduced matrix result type (the array type is the same): */
-    typedef cml::matrix<typename ScalarPromote<S,E>::type, AT, BO, L> type;
-
-    /* The deduced temporary type: */
-    typedef typename type::temporary_type temporary_type;
-};
-
-/** Type promotion for outer product. */
-template<typename E1, class AT1, typename E2, class AT2>
-struct MatrixPromote< cml::vector<E1,AT1>, cml::vector<E2,AT2> >
-{
-    typedef cml::vector<E1,AT1> left_type;
-    typedef cml::vector<E2,AT2> right_type;
-    typedef CML_DEFAULT_BASIS_ORIENTATION basis_orient;
-
-    /* Get matrix size: */
-    enum {
-        array_rows = left_type::array_size,
-        array_cols = right_type::array_size
-    };
-
-    /* Deduce the corresponding matrix types for the vectors: */
-    typedef CML_DEFAULT_ARRAY_LAYOUT layout;
-    typedef typename select_if<
-        array_rows == -1, dynamic<>, fixed<array_rows,1>
-    >::result left_storage;
-    typedef cml::matrix<E1,left_storage,basis_orient,layout> left_matrix;
-
-    typedef typename select_if<
-        array_cols == -1, dynamic<>, fixed<1,array_cols>
-    >::result right_storage;
-    typedef cml::matrix<E2,right_storage,basis_orient,layout> right_matrix;
-
-    /* Finally, promote the matrix types to get the result: */
-    typedef typename et::MatrixPromote<left_matrix,right_matrix>::type type;
-    typedef typename type::temporary_type temporary_type;
-};
-
 } // namespace et
 } // namespace cml
 
index 388abcf0a856cab52f4fac0cce683125a3f314c8..ab85945285a67a7bcc70f08956dea156e586c94d 100644 (file)
@@ -194,11 +194,18 @@ class MatrixAssignmentUnroller
 
   private:
     /* XXX Blah, a temp. hack to fix the auto-resizing stuff below. */
-    matrix_size hack_actual_size(const SrcT& /*src*/, scalar_result_tag) {
-        return matrix_size(1,1);
+    matrix_size hack_actual_size(
+        matrix_type& dest, const SrcT& /*src*/, scalar_result_tag
+        )
+    {
+        typedef ExprTraits<matrix_type> dest_traits;
+        return dest_traits().size(dest);
     }
 
-    matrix_size hack_actual_size(const SrcT& src, matrix_result_tag) {
+    matrix_size hack_actual_size(
+        matrix_type& /*dest*/, const SrcT& src, matrix_result_tag
+        )
+    {
         typedef ExprTraits<SrcT> src_traits;
         return src_traits().size(src);
     }
@@ -209,7 +216,7 @@ class MatrixAssignmentUnroller
 #if defined(CML_AUTOMATIC_MATRIX_RESIZE_ON_ASSIGNMENT)
         /* Get the size of src.  This also causes src to check its size: */
         matrix_size N = hack_actual_size(
-                src, typename src_traits::result_tag());
+            dest, src, typename src_traits::result_tag());
 
         /* Set the destination matrix's size: */
         dest.resize(N.first,N.second);
@@ -224,7 +231,8 @@ class MatrixAssignmentUnroller
     {
         return CheckedSize(dest,src,dynamic_size_tag());
     }
-    /* XXX Blah, a temp. hack to fix the auto-resizing stuff below. */
+
+
   public:
 
 
index 771f34ad0424098a84e895dcb4aa161f5c7a25b2..6f320f376326353b2c369cff29057d1f4e2510fc 100644 (file)
@@ -445,6 +445,13 @@ class quaternion
         return (*this = *this * e);
     }
 
+    /** Return access to the data as a raw pointer. */
+    typename vector_type::pointer data() { return m_q.data(); }
+
+    /** Return access to the data as a const raw pointer. */
+    const typename vector_type::pointer data() const { return m_q.data(); }
+
+
     /* NOTE: Quaternion division no longer supported, but I'm leaving the
        code here for reference (Jesse) */
 
index 0fcca0099ec7fcaab94d5eaf83abc4e410d0525f..8517c343cfc197ddbb07f6725161d809444b243f 100644 (file)
@@ -17,6 +17,13 @@ Boost Software License, v1.0 (see cml/LICENSE for details).
 #include <cstdlib>     // For std::rand.
 #include <cml/constants.h>
 
+#if defined(_MSC_VER)
+#pragma push_macro("min")
+#pragma push_macro("max")
+#undef min
+#undef max
+#endif
+
 namespace cml {
 
 /** Sign of input value as double. */
@@ -34,7 +41,7 @@ T clamp(T value, T min, T max) {
 /** Test input value for inclusion in [min, max]. */
 template < typename T >
 bool in_range(T value, T min, T max) {
-    return value >= min && value <= max;
+    return !(value < min) && !(value > max);
 }
 
 /** Map input value from [min1, max1] to [min2, max2]. */
@@ -63,12 +70,18 @@ T sqrt_safe(T value) {
 }
 
 
-/** For convenient squaring of expressions. */
+/** Square a value. */
 template < typename T >
 T sqr(T value) {
     return value * value;
 }
 
+/** Cube a value. */
+template < typename T >
+T cub(T value) {
+    return value * value * value;
+}
+
 /** Inverse square root. */
 template < typename T >
 T inv_sqrt(T value) {
@@ -247,6 +260,30 @@ T length(T x, T y, T z) {
     return std::sqrt(length_squared(x,y,z));
 }
 
+/** Index of maximum of 2 values. */
+template < typename T >
+size_t index_of_max(T a, T b) {
+    return a > b ? 0 : 1;
+}
+
+/** Index of maximum of 2 values by magnitude. */
+template < typename T >
+size_t index_of_max_abs(T a, T b) {
+    return index_of_max(std::fabs(a),std::fabs(b));
+}
+
+/** Index of minimum of 2 values. */
+template < typename T >
+size_t index_of_min(T a, T b) {
+    return a < b ? 0 : 1;
+}
+
+/** Index of minimum of 2 values by magnitude. */
+template < typename T >
+size_t index_of_min_abs(T a, T b) {
+    return index_of_min(std::fabs(a),std::fabs(b));
+}
+
 /** Index of maximum of 3 values. */
 template < typename T >
 size_t index_of_max(T a, T b, T c) {
@@ -320,6 +357,11 @@ T fov_to_zoom(T fov) {
 
 } // namespace cml
 
+#if defined(_MSC_VER)
+#pragma pop_macro("min")
+#pragma pop_macro("max")
+#endif
+
 #endif
 
 // -------------------------------------------------------------------------
index 0fa800ca259664472856077aec1b8a1b378e73ff..4fba063f2aae0e3eb9a68e280238578e4ba869cc 100644 (file)
@@ -37,6 +37,9 @@ class vector< Element, dynamic<Alloc> >
     /* Shorthand for the type of this vector: */
     typedef vector<Element,generator_type> vector_type;
 
+    /* The vector coordinate type: */
+    typedef Element coordinate_type;
+
     /* For integration into the expression template code: */
     typedef vector_type expr_type;
 
index bc9bc3fe9d29cda003b989736fae7af0fc4e836d..43c4c46f639b8baec51ae4b70fd33be8c23994c9 100644 (file)
@@ -42,6 +42,9 @@ class vector< Element, external<Size> >
     /* Shorthand for the type of this vector: */
     typedef vector<Element,generator_type> vector_type;
 
+    /* The vector coordinate type: */
+    typedef Element coordinate_type;
+
     /* For integration into the expression template code: */
     typedef vector_type expr_type;
 
@@ -74,6 +77,12 @@ class vector< Element, external<Size> >
     typedef cml::et::assignable_tag assignable_tag;
 
 
+  public:
+
+    /** Static constant containing the vector's space dimension. */
+    enum { dimension = Size };
+
+
   public:
 
     /** Return square of the length. */
index b0659383c580a2ed28efecdd8480069d43de98ca..6ec9d2076bd7116faa50447a1f8c7a99a292a25a 100644 (file)
@@ -39,6 +39,9 @@ class vector< Element, fixed<Size> >
     /* Shorthand for the type of this vector: */
     typedef vector<Element,generator_type> vector_type;
 
+    /* The vector coordinate type: */
+    typedef Element coordinate_type;
+
     /* For integration into the expression template code: */
     typedef vector_type expr_type;
 
@@ -68,6 +71,12 @@ class vector< Element, fixed<Size> >
     typedef cml::et::assignable_tag assignable_tag;
 
 
+  public:
+
+    /** Static constant containing the vector's space dimension. */
+    enum { dimension = Size };
+
+
   public:
 
     /** Return square of the length. */
@@ -124,6 +133,17 @@ class vector< Element, fixed<Size> >
         }
     }
 
+    /** Return a subvector by removing element i.
+     *
+     * @internal This is horribly inefficient...
+     */
+    subvector_type subvector(size_t i) const {
+        subvector_type s;
+        for(size_t m = 0, n = 0; m < this->size(); ++ m)
+            if(m != i) s[n++] = (*this)[m];
+        return s;
+    };
+
 
   public:
 
index cbb47642de29a105e9f9e1618c5326ace592b964..7106b324d6a404c42ac428fd509110f0420bcc5e 100644 (file)
@@ -21,11 +21,9 @@ namespace cml {
 template<typename E, class AT > inline std::ostream&
 operator<<(std::ostream& os, const vector<E,AT>& v)
 {
-    os << "[";
     for (size_t i = 0; i < v.size(); ++i) {
         os << " " << v[i];
     }
-    os << " ]";
     return os;
 }
 
@@ -33,11 +31,9 @@ operator<<(std::ostream& os, const vector<E,AT>& v)
 template< class XprT > inline std::ostream&
 operator<<(std::ostream& os, const et::VectorXpr<XprT>& v)
 {
-    os << "[";
     for (size_t i = 0; i < v.size(); ++i) {
         os << " " << v[i];
     }
-    os << " ]";
     return os;
 }
 
This page took 0.056053 seconds and 4 git commands to generate.