Skip to content

Commit 088a756

Browse files
committed
memory: simplify alignment procedure
1 parent 21f608d commit 088a756

File tree

2 files changed

+19
-94
lines changed

2 files changed

+19
-94
lines changed

include/eigenpy/alignment.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ struct aligned_storage {
2020
};
2121
};
2222

23+
template <class Data>
24+
struct aligned_instance {
25+
PyObject_VAR_HEAD PyObject *dict;
26+
PyObject *weakrefs;
27+
boost::python::instance_holder *objects;
28+
29+
typename aligned_storage<sizeof(Data)>::type storage;
30+
};
31+
2332
} // namespace eigenpy
2433

2534
namespace boost {

include/eigenpy/memory.hpp

Lines changed: 10 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,27 @@
11
/*
22
* Copyright 2014-2019, CNRS
3-
* Copyright 2018-2022, INRIA
3+
* Copyright 2018-2023, INRIA
44
*/
55

66
#ifndef __eigenpy_memory_hpp__
77
#define __eigenpy_memory_hpp__
88

99
#include "eigenpy/fwd.hpp"
1010

11-
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
12-
static inline void _Py_SET_SIZE(PyVarObject* ob, Py_ssize_t size) {
13-
ob->ob_size = size;
14-
}
15-
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
16-
#endif
17-
1811
/**
1912
* This section contains a convenience MACRO which allows an easy specialization
2013
* of Boost Python Object allocator for struct data types containing Eigen
2114
* objects and requiring strict alignment.
22-
*
23-
* This code was proposed as an stackoverflow answer:
24-
* http://stackoverflow.com/questions/13177573/how-to-expose-aligned-class-with-boost-python/29694518
25-
* Leading to this page proposing the solution:
26-
* http://fhtagn.net/prog/2015/04/16/quaternion_boost_python.html
27-
*
2815
*/
29-
#define EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(...) \
30-
namespace boost { \
31-
namespace python { \
32-
namespace objects { \
33-
template <> \
34-
struct instance<value_holder<__VA_ARGS__> > { \
35-
typedef value_holder<__VA_ARGS__> Data; \
36-
PyObject_VAR_HEAD PyObject* dict; \
37-
PyObject* weakrefs; \
38-
instance_holder* objects; \
39-
\
40-
typedef type_with_alignment< ::boost::alignment_of<Data>::value>::type \
41-
align_t; \
42-
\
43-
union { \
44-
align_t align; \
45-
char bytes[sizeof(Data) + EIGENPY_DEFAULT_ALIGN_BYTES]; \
46-
} storage; \
47-
}; \
48-
\
49-
template <class Derived> \
50-
struct make_instance_impl<__VA_ARGS__, value_holder<__VA_ARGS__>, Derived> { \
51-
typedef __VA_ARGS__ T; \
52-
typedef value_holder<__VA_ARGS__> Holder; \
53-
typedef objects::instance<Holder> instance_t; \
54-
\
55-
template <class Arg> \
56-
static inline PyObject* execute(Arg& x) { \
57-
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >)); \
58-
\
59-
PyTypeObject* type = Derived::get_class_object(x); \
60-
\
61-
if (type == 0) return python::detail::none(); \
62-
\
63-
PyObject* raw_result = type->tp_alloc( \
64-
type, objects::additional_instance_size<Holder>::value); \
65-
if (raw_result != 0) { \
66-
python::detail::decref_guard protect(raw_result); \
67-
instance_t* instance = (instance_t*)(void*)raw_result; \
68-
Holder* holder = \
69-
Derived::construct(&instance->storage, (PyObject*)instance, x); \
70-
holder->install(raw_result); \
71-
\
72-
Py_ssize_t holder_offset = \
73-
reinterpret_cast<Py_ssize_t>(holder) - \
74-
reinterpret_cast<Py_ssize_t>(&instance->storage) + \
75-
static_cast<Py_ssize_t>(offsetof(instance_t, storage)); \
76-
Py_SET_SIZE(instance, holder_offset); \
77-
\
78-
protect.cancel(); \
79-
} \
80-
return raw_result; \
81-
} \
82-
}; \
83-
\
84-
template <> \
85-
struct make_instance<__VA_ARGS__, value_holder<__VA_ARGS__> > \
86-
: make_instance_impl< \
87-
__VA_ARGS__, value_holder<__VA_ARGS__>, \
88-
make_instance<__VA_ARGS__, value_holder<__VA_ARGS__> > > { \
89-
template <class U> \
90-
static inline PyTypeObject* get_class_object(U&) { \
91-
return converter::registered<__VA_ARGS__>::converters \
92-
.get_class_object(); \
93-
} \
94-
\
95-
static inline value_holder<__VA_ARGS__>* construct( \
96-
void* storage, PyObject* instance, \
97-
reference_wrapper<__VA_ARGS__ const> x) { \
98-
void* aligned_storage = reinterpret_cast<void*>( \
99-
(reinterpret_cast<size_t>(storage) & \
100-
~(size_t(EIGENPY_DEFAULT_ALIGN_BYTES - 1))) + \
101-
EIGENPY_DEFAULT_ALIGN_BYTES); \
102-
value_holder<__VA_ARGS__>* new_holder = \
103-
new (aligned_storage) value_holder<__VA_ARGS__>(instance, x); \
104-
return new_holder; \
105-
} \
106-
}; \
107-
} \
108-
} \
16+
#define EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(...) \
17+
namespace boost { \
18+
namespace python { \
19+
namespace objects { \
20+
template <> \
21+
struct instance<value_holder<__VA_ARGS__> > \
22+
: ::eigenpy::aligned_instance<value_holder<__VA_ARGS__> > {}; \
23+
} \
24+
} \
10925
}
11026

11127
#endif // __eigenpy_memory_hpp__

0 commit comments

Comments
 (0)