From a848b86090f00df3c780ede83f6955ec0ef90fdf Mon Sep 17 00:00:00 2001
From: Jonathan Lambrechts <jonathan.lambrechts@uclouvain.be>
Date: Mon, 14 Sep 2020 18:10:47 +0200
Subject: [PATCH] fix isizefun in gmsh.h_cwrap

---
 api/GenApi.py    |  9 ++++++++-
 api/gmsh.h       |  2 +-
 api/gmsh.h_cwrap | 10 ++++++++--
 api/gmshc.cpp    |  2 +-
 api/gmshc.h      |  2 +-
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/api/GenApi.py b/api/GenApi.py
index 1a733014e6..f17cb3987e 100644
--- a/api/GenApi.py
+++ b/api/GenApi.py
@@ -738,7 +738,14 @@ def isizefun(name):
     a.cpp = "std::function<double(int, int, double, double, double)> " + name
     a.c_arg = "std::bind(" + name + ", std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, " + name + "_data)"
     a.c = "double (*" + name + ")(int dim, int tag, double x, double y, double z, void * data), void * " + name + "_data"
-    a.cwrap_arg = a.c_arg
+    a.cwrap_pre = "struct " + name + """_caller_  {
+          static double call(int entity_dim, int entity_tag, double x, double y, double z, void *callbackp) {
+            return (*static_cast<std::function<double(int,int,double,double,double)>*> (callbackp))(entity_dim, entity_tag, x, y, z);
+          }
+        };
+        auto *""" + name + "_ptr_ = new std::function<double(int,int,double,double,double)>("+name+""");
+"""
+    a.cwrap_arg = "&" + name + "_caller_::call, "+name+"_ptr_"
     a.python_pre = ("global api_" + name + "_type_\n" +
                     "            api_" + name + "_type_ = " +
                     "CFUNCTYPE(c_double, c_int, c_int, c_double, c_double, c_double)\n" +
diff --git a/api/gmsh.h b/api/gmsh.h
index 9c934c6ca8..f348df1b6c 100644
--- a/api/gmsh.h
+++ b/api/gmsh.h
@@ -1175,7 +1175,7 @@ namespace gmsh { // Top-level functions
       // Set a global mesh size callback. The callback should take 5 arguments
       // (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at
       // coordinates (`x', `y', `z').
-      GMSH_API void setSizeCallback(std::function<double(int,int,double,double,double)> callback);
+      GMSH_API void setSizeCallback(std::function<double(int, int, double, double, double)> callback);
 
       // gmsh::model::mesh::removeSizeCallback
       //
diff --git a/api/gmsh.h_cwrap b/api/gmsh.h_cwrap
index 20ce4e1854..70cf2198d7 100644
--- a/api/gmsh.h_cwrap
+++ b/api/gmsh.h_cwrap
@@ -1788,10 +1788,16 @@ namespace gmsh { // Top-level functions
       // Set a global mesh size callback. The callback should take 5 arguments
       // (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at
       // coordinates (`x', `y', `z').
-      inline void setSizeCallback(std::function<double(int,int,double,double,double)> callback)
+      inline void setSizeCallback(std::function<double(int, int, double, double, double)> callback)
       {
         int ierr = 0;
-        gmshModelMeshSetSizeCallback(std::bind(callback, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, callback_data), &ierr);
+        struct callback_caller_  {
+          static double call(int entity_dim, int entity_tag, double x, double y, double z, void *callbackp) {
+            return (*static_cast<std::function<double(int,int,double,double,double)>*> (callbackp))(entity_dim, entity_tag, x, y, z);
+          }
+        };
+        auto *callback_ptr_ = new std::function<double(int,int,double,double,double)>(callback);
+        gmshModelMeshSetSizeCallback(&callback_caller_::call, callback_ptr_, &ierr);
         if(ierr) throwLastError();
       }
 
diff --git a/api/gmshc.cpp b/api/gmshc.cpp
index b1bbde07d1..873baf36f3 100644
--- a/api/gmshc.cpp
+++ b/api/gmshc.cpp
@@ -1508,7 +1508,7 @@ GMSH_API void gmshModelMeshSetSizeAtParametricPoints(const int dim, const int ta
   }
 }
 
-GMSH_API void gmshModelMeshSetSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z, void *data), void *callback_data, int * ierr)
+GMSH_API void gmshModelMeshSetSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z, void * data), void * callback_data, int * ierr)
 {
   if(ierr) *ierr = 0;
   try {
diff --git a/api/gmshc.h b/api/gmshc.h
index a29f3824d2..5f3afcbcc1 100644
--- a/api/gmshc.h
+++ b/api/gmshc.h
@@ -1033,7 +1033,7 @@ GMSH_API void gmshModelMeshSetSizeAtParametricPoints(const int dim,
 /* Set a global mesh size callback. The callback should take 5 arguments
  * (`dim', `tag', `x', `y' and `z') and return the value of the mesh size at
  * coordinates (`x', `y', `z'). */
-GMSH_API void gmshModelMeshSetSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z, void *data), void *callback_data,
+GMSH_API void gmshModelMeshSetSizeCallback(double (*callback)(int dim, int tag, double x, double y, double z, void * data), void * callback_data,
                                            int * ierr);
 
 /* Remove the global mesh size callback. */
-- 
GitLab