1ac0f0486022fb1798579c9a550154e839770efa9Devang Patel// This file is part of Eigen, a lightweight C++ template library
2ac0f0486022fb1798579c9a550154e839770efa9Devang Patel// for linear algebra.
3ac0f0486022fb1798579c9a550154e839770efa9Devang Patel//
4ac0f0486022fb1798579c9a550154e839770efa9Devang Patel// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5ac0f0486022fb1798579c9a550154e839770efa9Devang Patel//
6ac0f0486022fb1798579c9a550154e839770efa9Devang Patel// This Source Code Form is subject to the terms of the Mozilla
7ac0f0486022fb1798579c9a550154e839770efa9Devang Patel// Public License v. 2.0. If a copy of the MPL was not distributed
8ac0f0486022fb1798579c9a550154e839770efa9Devang Patel// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
10ac0f0486022fb1798579c9a550154e839770efa9Devang Patel#include "main.h"
11ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
12ac0f0486022fb1798579c9a550154e839770efa9Devang Patelstruct TestNew1
13ac0f0486022fb1798579c9a550154e839770efa9Devang Patel{
14ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  MatrixXd m; // good: m will allocate its own array, taking care of alignment.
15ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  TestNew1() : m(20,20) {}
16ac0f0486022fb1798579c9a550154e839770efa9Devang Patel};
17ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
18ac0f0486022fb1798579c9a550154e839770efa9Devang Patelstruct TestNew2
19ac0f0486022fb1798579c9a550154e839770efa9Devang Patel{
20ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  Matrix3d m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned,
21ac0f0486022fb1798579c9a550154e839770efa9Devang Patel              // 8-byte alignment is good enough here, which we'll get automatically
22ac0f0486022fb1798579c9a550154e839770efa9Devang Patel};
23e60540f380cc9466f3b2f7d17adfd37db137689cDevang Patel
24e60540f380cc9466f3b2f7d17adfd37db137689cDevang Patelstruct TestNew3
25e60540f380cc9466f3b2f7d17adfd37db137689cDevang Patel{
26e60540f380cc9466f3b2f7d17adfd37db137689cDevang Patel  Vector2f m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned
27a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel};
28a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
29a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patelstruct TestNew4
30a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel{
31a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
32a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  Vector2d m;
33a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  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
348ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper};
358ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper
368ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topperstruct TestNew5
378ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper{
388ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
398ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  float f; // try the f at first -- the EIGEN_ALIGN16 attribute of m should make that still work
408ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  Matrix4f m;
418ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper};
428ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper
438ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topperstruct TestNew6
448ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper{
458ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  Matrix<float,2,2,DontAlign> m; // good: no alignment requested
468ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  float f;
478ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper};
484bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper
494bef961baf9660f1ac5a5b80378631cd942636b2Craig Toppertemplate<bool Align> struct Depends
504bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper{
514bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(Align)
524bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  Vector2d m;
534bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  float f;
544bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper};
55cf0e269d16f3d784b428c9b1b1e22d1f9e8bb91dDevang Patel
56cf0e269d16f3d784b428c9b1b1e22d1f9e8bb91dDevang Pateltemplate<typename T>
57cf0e269d16f3d784b428c9b1b1e22d1f9e8bb91dDevang Patelvoid check_unalignedassert_good()
58fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel{
59fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel  T *x, *y;
603b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel  x = new T;
613b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel  delete x;
623b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel  y = new T[2];
63885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  delete[] y;
64885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel}
65885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel
660d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis#if EIGEN_ALIGN_STATICALLY
670d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davistemplate<typename T>
680d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davisvoid construct_at_boundary(int boundary)
690d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis{
700d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  char buf[sizeof(T)+256];
710d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  size_t _buf = reinterpret_cast<size_t>(buf);
720d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  _buf += (16 - (_buf % 16)); // make 16-byte aligned
730d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  _buf += boundary; // make exact boundary-aligned
740d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  T *x = ::new(reinterpret_cast<void*>(_buf)) T;
750d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  x[0].setZero(); // just in order to silence warnings
760d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis  x->~T();
770d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis}
780d82fe77f2b6f48b5fab131c1671169d154f8c69Charles Davis#endif
79
80void unalignedassert()
81{
82  #if EIGEN_ALIGN_STATICALLY
83  construct_at_boundary<Vector2f>(4);
84  construct_at_boundary<Vector3f>(4);
85  construct_at_boundary<Vector4f>(16);
86  construct_at_boundary<Matrix2f>(16);
87  construct_at_boundary<Matrix3f>(4);
88  construct_at_boundary<Matrix4f>(16);
89
90  construct_at_boundary<Vector2d>(16);
91  construct_at_boundary<Vector3d>(4);
92  construct_at_boundary<Vector4d>(16);
93  construct_at_boundary<Matrix2d>(16);
94  construct_at_boundary<Matrix3d>(4);
95  construct_at_boundary<Matrix4d>(16);
96
97  construct_at_boundary<Vector2cf>(16);
98  construct_at_boundary<Vector3cf>(4);
99  construct_at_boundary<Vector2cd>(16);
100  construct_at_boundary<Vector3cd>(16);
101  #endif
102
103  check_unalignedassert_good<TestNew1>();
104  check_unalignedassert_good<TestNew2>();
105  check_unalignedassert_good<TestNew3>();
106
107  check_unalignedassert_good<TestNew4>();
108  check_unalignedassert_good<TestNew5>();
109  check_unalignedassert_good<TestNew6>();
110  check_unalignedassert_good<Depends<true> >();
111
112#if EIGEN_ALIGN_STATICALLY
113  VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8));
114  VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(8));
115  VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8));
116  VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4d>(8));
117  VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix2d>(8));
118  VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4d>(8));
119  VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cf>(8));
120  VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cd>(8));
121#endif
122}
123
124void test_unalignedassert()
125{
126  CALL_SUBTEST(unalignedassert());
127}
128