Skip to content

Instantly share code, notes, and snippets.

@ColinKennedy
Created September 16, 2022 06:33
Show Gist options
  • Save ColinKennedy/ed6ee24870498d2ee859d739846eb851 to your computer and use it in GitHub Desktop.
Save ColinKennedy/ed6ee24870498d2ee859d739846eb851 to your computer and use it in GitHub Desktop.
A somewhat oversimplified explanation on how to expose std::vector<std::pair<std::string, std::string>> to Boost.Python
#pragma once
/// Reference: https://github.com/snoyer/tictactoebot/blob/64b1e06937147e3e54ce4dcc465b7f76e1889ec6/opencv/pythonhelpers.h
#include <boost/python.hpp>
namespace py = boost::python;
template<typename T1, typename T2>
struct PairToPythonConverter
{
static PyObject* convert(std::pair<T1, T2> const &pair)
{
return py::incref(py::make_tuple(pair.first, pair.second).ptr());
}
};
template<typename T1, typename T2>
struct PythonToPairConverter
{
PythonToPairConverter()
{
py::converter::registry::push_back(&this->convertible, &this->construct, py::type_id<std::pair<T1, T2>>());
}
static void *convertible(PyObject *obj)
{
if (!PyTuple_CheckExact(obj)) return 0;
if (PyTuple_Size(obj) != 2) return 0;
return obj;
}
static void construct(PyObject *obj, py::converter::rvalue_from_python_stage1_data *data)
{
py::tuple tuple(py::borrowed(obj));
void* storage = ((py::converter::rvalue_from_python_storage<std::pair<T1, T2>>*) data)->storage.bytes;
new (storage) std::pair<T1, T2>(py::extract<T1>(tuple[0]), py::extract<T2>(tuple[1]));
data->convertible = storage;
}
};
template<typename T1, typename T2>
struct PyPair
{
py::to_python_converter<std::pair<T1, T2>, PairToPythonConverter<T1, T2>> toPy;
PythonToPairConverter<T1, T2> fromPy;
};
#include <boost/python.hpp>
#include <string>
#include <utility>
#include <vector>
#include "pyPair.h"
template <typename ContainerType>
struct SequenceToPython
{
static PyObject* convert(ContainerType const &container)
{
bp::list result;
for (auto const item : container)
{
result.append(item);
}
return boost::python::incref(result.ptr());
}
};
BOOST_PYTHON_MODULE(context)
{
PyPair<std::string, std::string>();
bp::to_python_converter<
std::vector<std::pair<std::string, std::string>>
SequenceToPython<std::vector<std::pair<std::string, std::string>>>
>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment