// // Copyright 2017 Ettus Research, a National Instruments Company // // SPDX-License-Identifier: GPL-3.0-or-later // #pragma once #include #include #include #include namespace bp = boost::python; template struct map_to_python_dict { static PyObject* convert(MapType const& input_map) { bp::dict py_dict; for (const auto& element : input_map) { py_dict[element.first] = element.second; } return bp::incref(py_dict.ptr()); } }; template struct iterable_to_python_list { static PyObject* convert(Container const& input) { bp::list py_list; for (const auto& element : input) { py_list.append(element); } return bp::incref(py_list.ptr()); } }; // Converter for std::vector / std::list arguments from python iterables struct iterable_converter { template iterable_converter& from_python() { bp::converter::registry::push_back(&iterable_converter::convertible, &iterable_converter::construct, bp::type_id()); return *this; } static void* convertible(PyObject* object) { return PyObject_GetIter(object) ? object : NULL; } template static void construct( PyObject* object, bp::converter::rvalue_from_python_stage1_data* data) { // Object is a borrowed reference, so create a handle indicting it is // borrowed for proper reference counting. bp::handle<> handle(bp::borrowed(object)); // Obtain a handle to the memory block that the converter has allocated // for the C++ type. typedef bp::converter::rvalue_from_python_storage storage_type; void* storage = reinterpret_cast(data)->storage.bytes; typedef bp::stl_input_iterator iterator; // Allocate the C++ type into the converter's memory block, and assign // its handle to the converter's convertible variable. The C++ // container is populated by passing the begin and end iterators of // the python object to the container's constructor. new (storage) Container(iterator(bp::object(handle)), // begin iterator()); // end data->convertible = storage; } }; void export_converter() { // LIBMPM_BOOST_PREAMBLE("helper") bp::to_python_converter, iterable_to_python_list>, false>(); }