Skip to content

Commit 0deef65

Browse files
committed
core: add alignment support
1 parent 2a6d963 commit 0deef65

File tree

3 files changed

+120
-1
lines changed

3 files changed

+120
-1
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2014-2019 CNRS Copyright (c) 2018-2022 INRIA
2+
# Copyright (c) 2014-2019 CNRS Copyright (c) 2018-2023 INRIA
33
#
44

55
cmake_minimum_required(VERSION 3.1)
@@ -130,6 +130,7 @@ set(${PROJECT_NAME}_HEADERS
130130
${${PROJECT_NAME}_UTILS_HEADERS}
131131
${${PROJECT_NAME}_SOLVERS_HEADERS}
132132
${${PROJECT_NAME}_DECOMPOSITIONS_HEADERS}
133+
include/eigenpy/alignment.hpp
133134
include/eigenpy/computation-info.hpp
134135
include/eigenpy/eigenpy.hpp
135136
include/eigenpy/exception.hpp

include/eigenpy/alignment.hpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2023, INRIA
3+
*/
4+
5+
#ifndef __eigenpy_alignment_hpp__
6+
#define __eigenpy_alignment_hpp__
7+
8+
#include <boost/python/detail/referent_storage.hpp>
9+
#include <boost/python/converter/arg_from_python.hpp>
10+
#include <boost/python/converter/rvalue_from_python_data.hpp>
11+
#include <boost/type_traits/aligned_storage.hpp>
12+
13+
namespace eigenpy {
14+
15+
template <std::size_t size, std::size_t alignment = EIGENPY_DEFAULT_ALIGN_BYTES>
16+
struct aligned_storage {
17+
union type {
18+
typename ::boost::aligned_storage<size, alignment>::type data;
19+
char bytes[size];
20+
};
21+
};
22+
23+
} // namespace eigenpy
24+
25+
namespace boost {
26+
namespace python {
27+
namespace detail {
28+
29+
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows,
30+
int MaxCols>
31+
struct referent_storage<
32+
Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &> {
33+
typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T;
34+
typedef
35+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
36+
};
37+
38+
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows,
39+
int MaxCols>
40+
struct referent_storage<
41+
const Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &> {
42+
typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T;
43+
typedef
44+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
45+
};
46+
47+
template <typename Scalar, int Options>
48+
struct referent_storage<Eigen::Quaternion<Scalar, Options> &> {
49+
typedef Eigen::Quaternion<Scalar, Options> T;
50+
typedef
51+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
52+
};
53+
54+
template <typename Scalar, int Options>
55+
struct referent_storage<const Eigen::Quaternion<Scalar, Options> &> {
56+
typedef Eigen::Quaternion<Scalar, Options> T;
57+
typedef
58+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
59+
};
60+
61+
} // namespace detail
62+
} // namespace python
63+
} // namespace boost
64+
65+
namespace eigenpy {
66+
67+
template <class T>
68+
struct call_destructor {
69+
static void run(void *bytes) {
70+
typedef typename boost::remove_const<
71+
typename boost::remove_reference<T>::type>::type T_;
72+
static_cast<T_ *>((void *)bytes)->~T_();
73+
}
74+
};
75+
76+
template <class T>
77+
struct rvalue_from_python_data
78+
: ::boost::python::converter::rvalue_from_python_storage<T> {
79+
#if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && \
80+
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \
81+
(!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) && \
82+
!defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing \
83+
this */
84+
// This must always be a POD struct with m_data its first member.
85+
BOOST_STATIC_ASSERT(
86+
BOOST_PYTHON_OFFSETOF(
87+
::boost::python::converter::rvalue_from_python_storage<T>, stage1) ==
88+
0);
89+
#endif
90+
91+
// The usual constructor
92+
rvalue_from_python_data(
93+
::boost::python::converter::rvalue_from_python_stage1_data const
94+
&_stage1) {
95+
this->stage1 = _stage1;
96+
}
97+
98+
// This constructor just sets m_convertible -- used by
99+
// implicitly_convertible<> to perform the final step of the
100+
// conversion, where the construct() function is already known.
101+
rvalue_from_python_data(void *convertible) {
102+
this->stage1.convertible = convertible;
103+
}
104+
105+
// Destroys any object constructed in the storage.
106+
~rvalue_from_python_data() {
107+
if (this->stage1.convertible == this->storage.bytes) {
108+
void *storage = reinterpret_cast<void *>(this->storage.bytes);
109+
call_destructor<T>::run(storage);
110+
}
111+
}
112+
};
113+
114+
} // namespace eigenpy
115+
116+
#endif // __eigenpy_alignment_hpp__

include/eigenpy/fwd.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ template <typename MatType,
4747
struct EigenFromPy;
4848
} // namespace eigenpy
4949

50+
#include "eigenpy/alignment.hpp"
51+
5052
#endif // ifndef __eigenpy_fwd_hpp__

0 commit comments

Comments
 (0)