#ifdef NG_PYTHON // BEGIN EVIL HACK: Patch PyThread_get_key_value inside pybind11 to avoid deadlocks // see https://github.com/pybind/pybind11/pull/1211 #include #include namespace pybind11 { inline void * PyThread_get_key_value(int state) { PyThreadState *tstate = (PyThreadState *) ::PyThread_get_key_value(state); if (!tstate) tstate = PyGILState_GetThisThreadState(); return tstate; } } // END EVIL HACK #include #include #include namespace py = pybind11; #include #include template py::array MoveToNumpy(std::vector& vec) { auto newvec = new std::vector(); std::swap(*newvec, vec); auto capsule = py::capsule(newvec, [](void *v) { delete reinterpret_cast*>(v); }); return py::array(newvec->size(), newvec->data(), capsule); } namespace PYBIND11_NAMESPACE { template bool CheckCast( py::handle obj ) { try{ obj.cast(); return true; } catch (py::cast_error &e) { return false; } } template struct extract { py::handle obj; extract( py::handle aobj ) : obj(aobj) {} bool check() { return CheckCast(obj); } T operator()() { return obj.cast(); } }; } struct NGDummyArgument {}; inline void NOOP_Deleter(void *) { ; } namespace netgen { ////////////////////////////////////////////////////////////////////// // Lambda to function pointer conversion template struct function_traits : public function_traits {}; template struct function_traits { typedef ReturnType (*pointer)(Args...); typedef ReturnType return_type; }; template typename function_traits::pointer FunctionPointer (const Function& lambda) { return static_cast::pointer>(lambda); } template inline std::string ToString (const T& t) { std::stringstream ss; ss << t; return ss.str(); } } #endif