diff --git a/include/eigenpy/eigen-allocator.hpp b/include/eigenpy/eigen-allocator.hpp
index 589159d011344df66a5a44c7ab4ee058bc13aa8d..a9d816251945c98a577de43279c0bf0390a14568 100644
--- a/include/eigenpy/eigen-allocator.hpp
+++ b/include/eigenpy/eigen-allocator.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2014-2020 CNRS INRIA
+// Copyright (c) 2014-2023 CNRS INRIA
 //
 
 #ifndef __eigenpy_eigen_allocator_hpp__
@@ -115,8 +115,11 @@ struct cast_matrix_or_array<Scalar, NewScalar, false> {
       mat, NumpyMap<MatType, NewScalar>::map(                                 \
                pyArray, details::check_swap(pyArray, mat)))
 
+template <typename EigenType>
+struct EigenAllocator;
+
 template <typename MatType>
-struct EigenAllocator {
+struct eigen_allocator_impl {
   typedef MatType Type;
   typedef typename MatType::Scalar Scalar;
 
@@ -130,8 +133,17 @@ struct EigenAllocator {
     Type *mat_ptr = details::init_matrix_or_array<Type>::run(pyArray, raw_ptr);
     Type &mat = *mat_ptr;
 
+    copy(pyArray, mat);
+  }
+
+  /// \brief Copy Python array into the input matrix mat.
+  template <typename MatrixDerived>
+  static void copy(PyArrayObject *pyArray,
+                   const Eigen::MatrixBase<MatrixDerived> &mat_) {
+    MatrixDerived &mat = mat_.const_cast_derived();
     const int pyArray_type_code = EIGENPY_GET_PY_ARRAY_TYPE(pyArray);
     const int Scalar_type_code = Register::getTypeCode<Scalar>();
+
     if (pyArray_type_code == Scalar_type_code) {
       mat = NumpyMap<MatType, Scalar>::map(
           pyArray, details::check_swap(pyArray, mat));  // avoid useless cast
@@ -185,13 +197,10 @@ struct EigenAllocator {
     const int pyArray_type_code = EIGENPY_GET_PY_ARRAY_TYPE(pyArray);
     const int Scalar_type_code = Register::getTypeCode<Scalar>();
 
-    typedef typename NumpyMap<MatType, Scalar>::EigenMap MapType;
-
     if (pyArray_type_code == Scalar_type_code)  // no cast needed
     {
-      MapType map_pyArray = NumpyMap<MatType, Scalar>::map(
-          pyArray, details::check_swap(pyArray, mat));
-      map_pyArray = mat;
+      NumpyMap<MatType, Scalar>::map(pyArray,
+                                     details::check_swap(pyArray, mat)) = mat;
       return;
     }
 
@@ -253,7 +262,7 @@ inline bool is_arr_layout_compatible_with_mat_type(PyArrayObject *pyArray) {
 }
 
 template <typename MatType, int Options, typename Stride>
-struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
+struct eigen_allocator_impl<Eigen::Ref<MatType, Options, Stride> > {
   typedef Eigen::Ref<MatType, Options, Stride> RefType;
   typedef typename MatType::Scalar Scalar;
 
@@ -296,49 +305,7 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
       new (raw_ptr) StorageType(mat_ref, pyArray, mat_ptr);
 
       RefType &mat = *reinterpret_cast<RefType *>(raw_ptr);
-      if (pyArray_type_code == Scalar_type_code) {
-        mat = NumpyMap<MatType, Scalar>::map(
-            pyArray, details::check_swap(pyArray, mat));  // avoid useless cast
-        return;
-      }
-
-      switch (pyArray_type_code) {
-        case NPY_INT:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, int, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_LONG:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, long, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_FLOAT:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, float, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_CFLOAT:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
-              MatType, std::complex<float>, Scalar, pyArray, mat);
-          break;
-        case NPY_DOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, double, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_CDOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
-              MatType, std::complex<double>, Scalar, pyArray, mat);
-          break;
-        case NPY_LONGDOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, long double,
-                                                    Scalar, pyArray, mat);
-          break;
-        case NPY_CLONGDOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
-              MatType, std::complex<long double>, Scalar, pyArray, mat);
-          break;
-        default:
-          throw Exception(
-              "You asked for a conversion which is not implemented.");
-      }
+      EigenAllocator<MatType>::copy(pyArray, mat);
     } else {
       assert(pyArray_type_code == Scalar_type_code);
       typename NumpyMap<MatType, Scalar, Options, NumpyMapStride>::EigenMap
@@ -355,7 +322,7 @@ struct EigenAllocator<Eigen::Ref<MatType, Options, Stride> > {
 };
 
 template <typename MatType, int Options, typename Stride>
-struct EigenAllocator<const Eigen::Ref<const MatType, Options, Stride> > {
+struct eigen_allocator_impl<const Eigen::Ref<const MatType, Options, Stride> > {
   typedef const Eigen::Ref<const MatType, Options, Stride> RefType;
   typedef typename MatType::Scalar Scalar;
 
@@ -399,49 +366,7 @@ struct EigenAllocator<const Eigen::Ref<const MatType, Options, Stride> > {
       new (raw_ptr) StorageType(mat_ref, pyArray, mat_ptr);
 
       MatType &mat = *mat_ptr;
-      if (pyArray_type_code == Scalar_type_code) {
-        mat = NumpyMap<MatType, Scalar>::map(
-            pyArray, details::check_swap(pyArray, mat));  // avoid useless cast
-        return;
-      }
-
-      switch (pyArray_type_code) {
-        case NPY_INT:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, int, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_LONG:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, long, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_FLOAT:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, float, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_CFLOAT:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
-              MatType, std::complex<float>, Scalar, pyArray, mat);
-          break;
-        case NPY_DOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, double, Scalar,
-                                                    pyArray, mat);
-          break;
-        case NPY_CDOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
-              MatType, std::complex<double>, Scalar, pyArray, mat);
-          break;
-        case NPY_LONGDOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, long double,
-                                                    Scalar, pyArray, mat);
-          break;
-        case NPY_CLONGDOUBLE:
-          EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
-              MatType, std::complex<long double>, Scalar, pyArray, mat);
-          break;
-        default:
-          throw Exception(
-              "You asked for a conversion which is not implemented.");
-      }
+      EigenAllocator<MatType>::copy(pyArray, mat);
     } else {
       assert(pyArray_type_code == Scalar_type_code);
       typename NumpyMap<MatType, Scalar, Options, NumpyMapStride>::EigenMap
@@ -457,6 +382,10 @@ struct EigenAllocator<const Eigen::Ref<const MatType, Options, Stride> > {
   }
 };
 #endif
+
+template <typename EigenType>
+struct EigenAllocator : eigen_allocator_impl<EigenType> {};
+
 }  // namespace eigenpy
 
 #endif  // __eigenpy_eigen_allocator_hpp__