diff --git a/cmake b/cmake index 1a6db988dbc0c02679d0566d8f3f50dd0aebc569..9403226002b930d592ca83b50d3cd714a1c2dc01 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 1a6db988dbc0c02679d0566d8f3f50dd0aebc569 +Subproject commit 9403226002b930d592ca83b50d3cd714a1c2dc01 diff --git a/include/eigenpy/alignment.hpp b/include/eigenpy/alignment.hpp index 2e0c9f51d91a82492a9e756a73f1db2bdcd816b8..b04a7d63a00fb90f43f192b0c1a86a13d1160814 100644 --- a/include/eigenpy/alignment.hpp +++ b/include/eigenpy/alignment.hpp @@ -20,6 +20,15 @@ struct aligned_storage { }; }; +template <class Data> +struct aligned_instance { + PyObject_VAR_HEAD PyObject *dict; + PyObject *weakrefs; + boost::python::instance_holder *objects; + + typename aligned_storage<sizeof(Data)>::type storage; +}; + } // namespace eigenpy namespace boost { @@ -62,6 +71,19 @@ struct referent_storage<const Eigen::Quaternion<Scalar, Options> &> { } // namespace python } // namespace boost +namespace boost { +namespace python { +namespace objects { + +// Force alignment of instance with value_holder +template <typename Derived> +struct instance<value_holder<Derived> > + : ::eigenpy::aligned_instance<value_holder<Derived> > {}; + +} // namespace objects +} // namespace python +} // namespace boost + namespace eigenpy { template <class T> diff --git a/include/eigenpy/fwd.hpp b/include/eigenpy/fwd.hpp index 0e2c54c736aafccc60f035cf125521276a7afab3..7db101c7a1545d7efccba8753dab0809d4216c47 100644 --- a/include/eigenpy/fwd.hpp +++ b/include/eigenpy/fwd.hpp @@ -5,6 +5,50 @@ #ifndef __eigenpy_fwd_hpp__ #define __eigenpy_fwd_hpp__ +#if defined(__clang__) +#define EIGENPY_CLANG_COMPILER +#elif defined(__GNUC__) +#define EIGENPY_GCC_COMPILER +#elif defined(_MSC_VER) +#define EIGENPY_MSVC_COMPILER +#endif + +#define EIGENPY_STRING_LITERAL(string) #string +#define EIGENPY_STRINGIZE(string) EIGENPY_STRING_LITERAL(string) +#define _EIGENPY_PPCAT(A, B) A##B +#define EIGENPY_PPCAT(A, B) _EIGENPY_PPCAT(A, B) +#define EIGENPY_STRINGCAT(A, B) A B + +// For more details, visit +// https://stackoverflow.com/questions/171435/portability-of-warning-preprocessor-directive +#if defined(EIGENPY_CLANG_COMPILER) || defined(EIGENPY_GCC_COMPILER) +#define EIGENPY_PRAGMA(x) _Pragma(#x) +#define EIGENPY_PRAGMA_MESSAGE(the_message) \ + EIGENPY_PRAGMA(GCC message the_message) +#define EIGENPY_PRAGMA_WARNING(the_message) \ + EIGENPY_PRAGMA(GCC warning the_message) +#define EIGENPY_PRAGMA_DEPRECATED(the_message) \ + EIGENPY_PRAGMA_WARNING(Deprecated : the_message) +#define EIGENPY_PRAGMA_DEPRECATED_HEADER(old_header, new_header) \ + EIGENPY_PRAGMA_WARNING( \ + Deprecated header file \ + : #old_header has been replaced \ + by #new_header.\n Please use #new_header instead of #old_header.) +#elif defined(WIN32) +#define EIGENPY_PRAGMA(x) __pragma(#x) +#define EIGENPY_PRAGMA_MESSAGE(the_message) \ + EIGENPY_PRAGMA(message(#the_message)) +#define EIGENPY_PRAGMA_WARNING(the_message) \ + EIGENPY_PRAGMA(message(EIGENPY_STRINGCAT("WARNING: ", the_message))) +#endif + +#define EIGENPY_DEPRECATED_MACRO(macro, the_message) \ + EIGENPY_PRAGMA_WARNING( \ + EIGENPY_STRINGCAT("this macro is deprecated: ", the_message)) +#define EIGENPY_DEPRECATED_FILE(the_message) \ + EIGENPY_PRAGMA_WARNING( \ + EIGENPY_STRINGCAT("this file is deprecated: ", the_message)) + #include "eigenpy/config.hpp" // Silence a warning about a deprecated use of boost bind by boost python diff --git a/include/eigenpy/memory.hpp b/include/eigenpy/memory.hpp index 5eaf0a2a7dc733e1f0cb13130e926579f276ae40..cbd8c482d291f79d6fdb9dd23bd92e2ca1fd4ffb 100644 --- a/include/eigenpy/memory.hpp +++ b/include/eigenpy/memory.hpp @@ -1,111 +1,23 @@ /* * Copyright 2014-2019, CNRS - * Copyright 2018-2022, INRIA + * Copyright 2018-2023, INRIA */ -#ifndef __eigenpy_memory_hpp__ -#define __eigenpy_memory_hpp__ - #include "eigenpy/fwd.hpp" -#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) -static inline void _Py_SET_SIZE(PyVarObject* ob, Py_ssize_t size) { - ob->ob_size = size; -} -#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) -#endif +EIGENPY_DEPRECATED_FILE( + "This header file is now useless and should not be included anymore.") + +#ifndef __eigenpy_memory_hpp__ +#define __eigenpy_memory_hpp__ /** * This section contains a convenience MACRO which allows an easy specialization * of Boost Python Object allocator for struct data types containing Eigen * objects and requiring strict alignment. - * - * This code was proposed as an stackoverflow answer: - * http://stackoverflow.com/questions/13177573/how-to-expose-aligned-class-with-boost-python/29694518 - * Leading to this page proposing the solution: - * http://fhtagn.net/prog/2015/04/16/quaternion_boost_python.html - * */ -#define EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(...) \ - namespace boost { \ - namespace python { \ - namespace objects { \ - template <> \ - struct instance<value_holder<__VA_ARGS__> > { \ - typedef value_holder<__VA_ARGS__> Data; \ - PyObject_VAR_HEAD PyObject* dict; \ - PyObject* weakrefs; \ - instance_holder* objects; \ - \ - typedef type_with_alignment< ::boost::alignment_of<Data>::value>::type \ - align_t; \ - \ - union { \ - align_t align; \ - char bytes[sizeof(Data) + EIGENPY_DEFAULT_ALIGN_BYTES]; \ - } storage; \ - }; \ - \ - template <class Derived> \ - struct make_instance_impl<__VA_ARGS__, value_holder<__VA_ARGS__>, Derived> { \ - typedef __VA_ARGS__ T; \ - typedef value_holder<__VA_ARGS__> Holder; \ - typedef objects::instance<Holder> instance_t; \ - \ - template <class Arg> \ - static inline PyObject* execute(Arg& x) { \ - BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >)); \ - \ - PyTypeObject* type = Derived::get_class_object(x); \ - \ - if (type == 0) return python::detail::none(); \ - \ - PyObject* raw_result = type->tp_alloc( \ - type, objects::additional_instance_size<Holder>::value); \ - if (raw_result != 0) { \ - python::detail::decref_guard protect(raw_result); \ - instance_t* instance = (instance_t*)(void*)raw_result; \ - Holder* holder = \ - Derived::construct(&instance->storage, (PyObject*)instance, x); \ - holder->install(raw_result); \ - \ - Py_ssize_t holder_offset = \ - reinterpret_cast<Py_ssize_t>(holder) - \ - reinterpret_cast<Py_ssize_t>(&instance->storage) + \ - static_cast<Py_ssize_t>(offsetof(instance_t, storage)); \ - Py_SET_SIZE(instance, holder_offset); \ - \ - protect.cancel(); \ - } \ - return raw_result; \ - } \ - }; \ - \ - template <> \ - struct make_instance<__VA_ARGS__, value_holder<__VA_ARGS__> > \ - : make_instance_impl< \ - __VA_ARGS__, value_holder<__VA_ARGS__>, \ - make_instance<__VA_ARGS__, value_holder<__VA_ARGS__> > > { \ - template <class U> \ - static inline PyTypeObject* get_class_object(U&) { \ - return converter::registered<__VA_ARGS__>::converters \ - .get_class_object(); \ - } \ - \ - static inline value_holder<__VA_ARGS__>* construct( \ - void* storage, PyObject* instance, \ - reference_wrapper<__VA_ARGS__ const> x) { \ - void* aligned_storage = reinterpret_cast<void*>( \ - (reinterpret_cast<size_t>(storage) & \ - ~(size_t(EIGENPY_DEFAULT_ALIGN_BYTES - 1))) + \ - EIGENPY_DEFAULT_ALIGN_BYTES); \ - value_holder<__VA_ARGS__>* new_holder = \ - new (aligned_storage) value_holder<__VA_ARGS__>(instance, x); \ - return new_holder; \ - } \ - }; \ - } \ - } \ - } +#define EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(...) \ + EIGENPY_DEPRECATED_MACRO(EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(), \ + "it is no more needed.") #endif // __eigenpy_memory_hpp__ diff --git a/unittest/std_vector.cpp b/unittest/std_vector.cpp index 12bb9e2cecf88b0a8b451d6685c03bc3f2e7a692..fa8a95e8a4d7d48c06c8b25cd6fd6076070af991 100644 --- a/unittest/std_vector.cpp +++ b/unittest/std_vector.cpp @@ -7,26 +7,24 @@ #include "eigenpy/eigen-from-python.hpp" #include "eigenpy/std-vector.hpp" -template <typename MatType, - typename Allocator = Eigen::aligned_allocator<MatType> > -void printVectorOfMatrix(const std::vector<MatType, Allocator> &Ms) { +template <typename MatType> +void printVectorOfMatrix( + const std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) { const std::size_t n = Ms.size(); for (std::size_t i = 0; i < n; i++) { std::cout << "el[" << i << "] =\n" << Ms[i] << '\n'; } } -template <typename MatType, - typename Allocator = Eigen::aligned_allocator<MatType> > -std::vector<MatType, Allocator> copy( - const std::vector<MatType, Allocator> &Ms) { - std::vector<MatType, Allocator> out = Ms; +template <typename MatType> +std::vector<MatType, Eigen::aligned_allocator<MatType> > copy( + const std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) { + std::vector<MatType, Eigen::aligned_allocator<MatType> > out = Ms; return out; } -template <typename MatType, - typename Allocator = Eigen::aligned_allocator<MatType> > -void setZero(std::vector<MatType, Allocator> &Ms) { +template <typename MatType> +void setZero(std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) { for (std::size_t i = 0; i < Ms.size(); i++) { Ms[i].setZero(); }