/* Construct from an existing Numpy array */ numpy_boost(PyObject* obj) throw (python_exception) : super(NULL, std::vector<typename super::index>(NDims, 0)), array(NULL) { PyArrayObject* a; a = (PyArrayObject*)PyArray_FromObject( obj, detail::numpy_type_map<T>::typenum, NDims, NDims); if (a == NULL) { throw python_exception(); } init_from_array(a); }
explicit numpy_boost(const ExtentsList& extents) throw (python_exception) : super(NULL, std::vector<typename super::index>(NDims, 0)), array(NULL) { npy_intp shape[NDims]; PyArrayObject* a; boost::detail::multi_array::copy_n(extents, NDims, shape); a = (PyArrayObject*)PyArray_SimpleNew( NDims, shape, detail::numpy_type_map<T>::typenum); if (a == NULL) { throw python_exception(); } init_from_array(a); }
numpy_boost( numpy_from_boost_array_proxy<Array> const& prx ) throw (python_exception): super(NULL, std::vector<typename super::index>(NDims, 0)), array(NULL) { static_assert(Array::dimensionality==NDims,"IncorrectDimensions"); npy_intp shape[NDims]; PyArrayObject* a; std::copy_n(prx.source_arr.shape(), NDims, shape); a = (PyArrayObject*)PyArray_SimpleNew( NDims, shape, detail::numpy_type_map<T>::typenum); if (a == NULL) { throw python_exception(); } std::copy_n( prx.source_arr.origin(), prx.source_arr.num_elements(), (T*)PyArray_DATA(a) ); init_from_array(a); }
std::vector<cmonster::core::Token> FunctionMacro::operator()( clang::SourceLocation const& expansion_location, std::vector<cmonster::core::Token> const& arguments) const { // Create the arguments tuple. ScopedPyObject args_tuple = PyTuple_New(arguments.size()); if (!args_tuple) throw std::runtime_error("Failed to create argument tuple"); for (Py_ssize_t i = 0; i < static_cast<Py_ssize_t>(arguments.size()); ++i) { Token *token = create_token(m_preprocessor, arguments[i]); PyTuple_SetItem(args_tuple, i, reinterpret_cast<PyObject*>(token)); } // Set the "preprocessor" and "location" global variables. // // XXX How do we create a closure via the C API? It would be better if we // could bind a function to the preprocessor it was created with, when we // define the function. PyObject *globals = PyEval_GetGlobals(); if (globals) { PyObject *key = PyUnicode_FromString("preprocessor"); if (!key) throw python_exception(); Py_INCREF((PyObject*)m_preprocessor); PyDict_SetItem(globals, key, (PyObject*)m_preprocessor); cmonster::core::Preprocessor &pp = get_preprocessor(m_preprocessor); SourceLocation *location = create_source_location( expansion_location, pp.getClangPreprocessor().getSourceManager()); if (!location) throw python_exception(); key = PyUnicode_FromString("location"); if (!key) throw python_exception(); PyDict_SetItem(globals, key, (PyObject*)location); } // Call the function. ScopedPyObject py_result = PyObject_Call(m_callable, args_tuple, NULL); if (!py_result) throw python_exception(); // Transform the result. std::vector<cmonster::core::Token> result; if (py_result == Py_None) return result; // Is it a string? If so, tokenize it. if (PyUnicode_Check(py_result)) { ScopedPyObject utf8(PyUnicode_AsUTF8String(py_result)); if (utf8) { char *u8_chars; Py_ssize_t u8_size; if (PyBytes_AsStringAndSize(utf8, &u8_chars, &u8_size) == -1) { throw python_exception(); } else { cmonster::core::Preprocessor &pp = get_preprocessor(m_preprocessor); result = pp.tokenize(u8_chars, u8_size); return result; } } else { throw python_exception(); } } // If it's not a string, it should be a sequence of Token objects. if (!PySequence_Check(py_result)) { throw python_exception(PyExc_TypeError, "macro functions must return a sequence of tokens"); } const Py_ssize_t seqlen = PySequence_Size(py_result); if (seqlen == -1) { throw python_exception(); } else { for (Py_ssize_t i = 0; i < seqlen; ++i) { ScopedPyObject token_ = PySequence_GetItem(py_result, i); if (PyObject_TypeCheck(token_, get_token_type())) { Token *token = (Token*)(PyObject*)token_; result.push_back(get_token(token)); } else { // Invalid return value. throw python_exception(PyExc_TypeError, "macro functions must return a sequence of tokens"); } } } return result; }