Home | History | Annotate | Download | only in eigen2
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra. Eigen itself is part of the KDE project.
      3 //
      4 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #include "main.h"
     11 
     12 struct Good1
     13 {
     14   MatrixXd m; // good: m will allocate its own array, taking care of alignment.
     15   Good1() : m(20,20) {}
     16 };
     17 
     18 struct Good2
     19 {
     20   Matrix3d m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be aligned
     21 };
     22 
     23 struct Good3
     24 {
     25   Vector2f m; // good: same reason
     26 };
     27 
     28 struct Bad4
     29 {
     30   Vector2d m; // bad: sizeof(m)%16==0 so alignment is required
     31 };
     32 
     33 struct Bad5
     34 {
     35   Matrix<float, 2, 6> m; // bad: same reason
     36 };
     37 
     38 struct Bad6
     39 {
     40   Matrix<double, 3, 4> m; // bad: same reason
     41 };
     42 
     43 struct Good7
     44 {
     45   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     46   Vector2d m;
     47   float f; // make the struct have sizeof%16!=0 to make it a little more tricky when we allow an array of 2 such objects
     48 };
     49 
     50 struct Good8
     51 {
     52   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     53   float f; // try the f at first -- the EIGEN_ALIGN_128 attribute of m should make that still work
     54   Matrix4f m;
     55 };
     56 
     57 struct Good9
     58 {
     59   Matrix<float,2,2,DontAlign> m; // good: no alignment requested
     60   float f;
     61 };
     62 
     63 template<bool Align> struct Depends
     64 {
     65   EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(Align)
     66   Vector2d m;
     67   float f;
     68 };
     69 
     70 template<typename T>
     71 void check_unalignedassert_good()
     72 {
     73   T *x, *y;
     74   x = new T;
     75   delete x;
     76   y = new T[2];
     77   delete[] y;
     78 }
     79 
     80 #if EIGEN_ARCH_WANTS_ALIGNMENT
     81 template<typename T>
     82 void check_unalignedassert_bad()
     83 {
     84   float buf[sizeof(T)+16];
     85   float *unaligned = buf;
     86   while((reinterpret_cast<std::size_t>(unaligned)&0xf)==0) ++unaligned; // make sure unaligned is really unaligned
     87   T *x = ::new(static_cast<void*>(unaligned)) T;
     88   x->~T();
     89 }
     90 #endif
     91 
     92 void unalignedassert()
     93 {
     94   check_unalignedassert_good<Good1>();
     95   check_unalignedassert_good<Good2>();
     96   check_unalignedassert_good<Good3>();
     97 #if EIGEN_ARCH_WANTS_ALIGNMENT
     98   VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad4>());
     99   VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad5>());
    100   VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad6>());
    101 #endif
    102 
    103   check_unalignedassert_good<Good7>();
    104   check_unalignedassert_good<Good8>();
    105   check_unalignedassert_good<Good9>();
    106   check_unalignedassert_good<Depends<true> >();
    107 
    108 #if EIGEN_ARCH_WANTS_ALIGNMENT
    109   VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Depends<false> >());
    110 #endif
    111 }
    112 
    113 void test_eigen2_unalignedassert()
    114 {
    115   CALL_SUBTEST(unalignedassert());
    116 }
    117