merge(3p/immer): Subtree merge at 'ad3e3556d' as 'third_party/immer'
Change-Id: I9636a41ad44b4218293833fd3e9456d9b07c731b
This commit is contained in:
commit
1213b086a1
311 changed files with 74223 additions and 0 deletions
80
third_party/immer/extra/python/src/immer-boost.cpp
vendored
Normal file
80
third_party/immer/extra/python/src/immer-boost.cpp
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// immer: immutable data structures for C++
|
||||
// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
|
||||
//
|
||||
// This software is distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
|
||||
|
||||
#include <immer/vector.hpp>
|
||||
#include <immer/refcount/unsafe_refcount_policy.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
struct heap_t
|
||||
{
|
||||
template <typename ...Tags>
|
||||
static void* allocate(std::size_t size, Tags...)
|
||||
{
|
||||
return PyMem_Malloc(size);
|
||||
}
|
||||
|
||||
template <typename ...Tags>
|
||||
static void deallocate(std::size_t, void* obj, Tags...)
|
||||
{
|
||||
PyMem_Free(obj);
|
||||
}
|
||||
};
|
||||
|
||||
using memory_t = immer::memory_policy<
|
||||
immer::unsafe_free_list_heap_policy<heap_t>,
|
||||
immer::unsafe_refcount_policy>;
|
||||
|
||||
template <typename Vector>
|
||||
struct immer_vector_indexing_suite : boost::python::vector_indexing_suite<
|
||||
Vector, true, immer_vector_indexing_suite<Vector>>
|
||||
{
|
||||
using value_t = typename Vector::value_type;
|
||||
using index_t = typename Vector::size_type;
|
||||
using object_t = boost::python::object;
|
||||
|
||||
static void forbidden() { throw std::runtime_error{"immutable!"}; }
|
||||
static void todo() { throw std::runtime_error{"TODO!"}; }
|
||||
|
||||
static const value_t& get_item(const Vector& v, index_t i) { return v[i]; }
|
||||
static object_t get_slice(const Vector&, index_t, index_t) { todo(); }
|
||||
|
||||
static void set_item(const Vector&, index_t, const value_t&) { forbidden(); }
|
||||
static void delete_item(const Vector&, index_t) { forbidden(); }
|
||||
static void set_slice(const Vector&, index_t, index_t, const value_t&) { forbidden(); }
|
||||
static void delete_slice(const Vector&, index_t, index_t) { forbidden(); }
|
||||
template <typename Iter>
|
||||
static void set_slice(const Vector&, index_t, index_t, Iter, Iter) { forbidden(); }
|
||||
template <class Iter>
|
||||
static void extend(const Vector& container, Iter, Iter) { forbidden(); }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(immer_python_module)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
using vector_t = immer::vector<object, memory_t>;
|
||||
|
||||
class_<vector_t>("Vector")
|
||||
.def(immer_vector_indexing_suite<vector_t>())
|
||||
.def("append",
|
||||
+[] (const vector_t& v, object x) {
|
||||
return v.push_back(std::move(x));
|
||||
})
|
||||
.def("set",
|
||||
+[] (const vector_t& v, std::size_t i, object x) {
|
||||
return v.set(i, std::move(x));
|
||||
})
|
||||
;
|
||||
}
|
||||
77
third_party/immer/extra/python/src/immer-pybind.cpp
vendored
Normal file
77
third_party/immer/extra/python/src/immer-pybind.cpp
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// immer: immutable data structures for C++
|
||||
// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
|
||||
//
|
||||
// This software is distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
#include <immer/vector.hpp>
|
||||
#include <immer/refcount/unsafe_refcount_policy.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
struct heap_t
|
||||
{
|
||||
template <typename ...Tags>
|
||||
static void* allocate(std::size_t size, Tags...)
|
||||
{
|
||||
return PyMem_Malloc(size);
|
||||
}
|
||||
|
||||
template <typename ...Tags>
|
||||
static void deallocate(std::size_t, void* obj, Tags...)
|
||||
{
|
||||
PyMem_Free(obj);
|
||||
}
|
||||
};
|
||||
|
||||
using memory_t = immer::memory_policy<
|
||||
immer::unsafe_free_list_heap_policy<heap_t>,
|
||||
immer::unsafe_refcount_policy>;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_PLUGIN(immer_python_module)
|
||||
{
|
||||
py::module m("immer", R"pbdoc(
|
||||
Immer
|
||||
-----
|
||||
.. currentmodule:: immer
|
||||
.. autosummary::
|
||||
:toctree: _generate
|
||||
Vector
|
||||
)pbdoc");
|
||||
|
||||
using vector_t = immer::vector<py::object, memory_t>;
|
||||
|
||||
py::class_<vector_t>(m, "Vector")
|
||||
.def(py::init<>())
|
||||
.def("__len__", &vector_t::size)
|
||||
.def("__getitem__",
|
||||
[] (const vector_t& v, std::size_t i) {
|
||||
if (i > v.size())
|
||||
throw py::index_error{"Index out of range"};
|
||||
return v[i];
|
||||
})
|
||||
.def("append",
|
||||
[] (const vector_t& v, py::object x) {
|
||||
return v.push_back(std::move(x));
|
||||
})
|
||||
.def("set",
|
||||
[] (const vector_t& v, std::size_t i, py::object x) {
|
||||
return v.set(i, std::move(x));
|
||||
});
|
||||
|
||||
#ifdef VERSION_INFO
|
||||
m.attr("__version__") = py::str(VERSION_INFO);
|
||||
#else
|
||||
m.attr("__version__") = py::str("dev");
|
||||
#endif
|
||||
|
||||
return m.ptr();
|
||||
}
|
||||
402
third_party/immer/extra/python/src/immer-raw.cpp
vendored
Normal file
402
third_party/immer/extra/python/src/immer-raw.cpp
vendored
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
//
|
||||
// immer: immutable data structures for C++
|
||||
// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
|
||||
//
|
||||
// This software is distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
}
|
||||
|
||||
#include <immer/vector.hpp>
|
||||
#include <immer/algorithm.hpp>
|
||||
#include <immer/refcount/unsafe_refcount_policy.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
struct heap_t
|
||||
{
|
||||
template <typename ...Tags>
|
||||
static void* allocate(std::size_t size, Tags...)
|
||||
{
|
||||
return PyMem_Malloc(size);
|
||||
}
|
||||
|
||||
template <typename ...Tags>
|
||||
static void deallocate(std::size_t, void* obj, Tags...)
|
||||
{
|
||||
PyMem_Free(obj);
|
||||
}
|
||||
};
|
||||
|
||||
struct object_t
|
||||
{
|
||||
struct wrap_t {};
|
||||
struct adopt_t {};
|
||||
|
||||
PyObject* ptr_ = nullptr;
|
||||
|
||||
object_t() = delete;
|
||||
~object_t() { Py_XDECREF(ptr_); }
|
||||
|
||||
explicit object_t(PyObject* p, wrap_t) : ptr_{p} {}
|
||||
explicit object_t(PyObject* p, adopt_t) : ptr_{p}
|
||||
{
|
||||
assert(p);
|
||||
Py_INCREF(p);
|
||||
}
|
||||
|
||||
static object_t wrap(PyObject* p) { return object_t{p, wrap_t{}}; }
|
||||
static object_t adopt(PyObject* p) { return object_t{p, adopt_t{}}; }
|
||||
|
||||
object_t(const object_t& o) : ptr_(o.ptr_) { Py_INCREF(ptr_); }
|
||||
object_t(object_t&& o) { std::swap(ptr_, o.ptr_); }
|
||||
|
||||
object_t& operator=(const object_t& o)
|
||||
{
|
||||
Py_XINCREF(o.ptr_);
|
||||
Py_XDECREF(ptr_);
|
||||
ptr_ = o.ptr_;
|
||||
return *this;
|
||||
}
|
||||
object_t& operator=(object_t&& o)
|
||||
{
|
||||
std::swap(ptr_, o.ptr_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PyObject* release()
|
||||
{
|
||||
auto p = ptr_;
|
||||
ptr_ = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
PyObject* get() const { return ptr_; }
|
||||
};
|
||||
|
||||
using memory_t = immer::memory_policy<
|
||||
immer::unsafe_free_list_heap_policy<heap_t>,
|
||||
immer::unsafe_refcount_policy>;
|
||||
|
||||
using vector_impl_t = immer::vector<object_t, memory_t>;
|
||||
|
||||
struct vector_t
|
||||
{
|
||||
PyObject_HEAD
|
||||
vector_impl_t impl;
|
||||
PyObject* in_weakreflist;
|
||||
|
||||
static PyTypeObject type;
|
||||
};
|
||||
|
||||
vector_t* empty_vector = nullptr;
|
||||
|
||||
vector_t* make_vector()
|
||||
{
|
||||
auto* v = PyObject_GC_New(vector_t, &vector_t::type);
|
||||
new (&v->impl) vector_impl_t{};
|
||||
v->in_weakreflist = nullptr;
|
||||
PyObject_GC_Track((PyObject*)v);
|
||||
return v;
|
||||
}
|
||||
|
||||
vector_t* make_vector(vector_impl_t&& impl)
|
||||
{
|
||||
auto v = PyObject_GC_New(vector_t, &vector_t::type);
|
||||
new (&v->impl) vector_impl_t{std::move(impl)};
|
||||
v->in_weakreflist = nullptr;
|
||||
PyObject_GC_Track((PyObject*)v);
|
||||
return v;
|
||||
}
|
||||
|
||||
auto todo()
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "immer: todo!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void vector_dealloc(vector_t* self)
|
||||
{
|
||||
if (self->in_weakreflist != nullptr)
|
||||
PyObject_ClearWeakRefs((PyObject*)self);
|
||||
|
||||
PyObject_GC_UnTrack((PyObject*)self);
|
||||
Py_TRASHCAN_SAFE_BEGIN(self);
|
||||
|
||||
self->impl.~vector_impl_t();
|
||||
|
||||
PyObject_GC_Del(self);
|
||||
Py_TRASHCAN_SAFE_END(self);
|
||||
}
|
||||
|
||||
PyObject* vector_to_list(vector_t* self)
|
||||
{
|
||||
auto list = PyList_New(self->impl.size());
|
||||
auto idx = 0;
|
||||
immer::for_each(self->impl, [&] (auto&& obj) {
|
||||
auto o = obj.get();
|
||||
Py_INCREF(o);
|
||||
PyList_SET_ITEM(list, idx, o);
|
||||
++idx;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
PyObject* vector_repr(vector_t *self)
|
||||
{
|
||||
auto list = vector_to_list(self);
|
||||
auto list_repr = PyObject_Repr(list);
|
||||
Py_DECREF(list);
|
||||
|
||||
if (!list_repr) return nullptr;
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
auto s = PyUnicode_FromFormat("%s%U%s", "immer.vector(", list_repr, ")");
|
||||
Py_DECREF(list_repr);
|
||||
#else
|
||||
auto s = PyString_FromString("immer.vector(");
|
||||
PyString_ConcatAndDel(&s, list_repr);
|
||||
PyString_ConcatAndDel(&s, PyString_FromString(")"));
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
Py_ssize_t vector_len(vector_t* self)
|
||||
{
|
||||
return self->impl.size();
|
||||
}
|
||||
|
||||
PyObject* vector_extend(vector_t* self, PyObject* iterable)
|
||||
{
|
||||
return todo();
|
||||
}
|
||||
|
||||
vector_t* vector_append(vector_t* self, PyObject *obj)
|
||||
{
|
||||
assert(obj != nullptr);
|
||||
return make_vector(self->impl.push_back(object_t::adopt(obj)));
|
||||
}
|
||||
|
||||
vector_t* vector_set(vector_t* self, PyObject* args)
|
||||
{
|
||||
PyObject* obj = nullptr;
|
||||
Py_ssize_t pos;
|
||||
// the n parses for size, the O parses for a Python object
|
||||
if(!PyArg_ParseTuple(args, "nO", &pos, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (pos < 0)
|
||||
pos += self->impl.size();
|
||||
if (pos < 0 || pos > (Py_ssize_t)self->impl.size()) {
|
||||
PyErr_Format(PyExc_IndexError, "Index out of range: %zi", pos);
|
||||
return nullptr;
|
||||
}
|
||||
return make_vector(self->impl.set(pos, object_t::adopt(obj)));
|
||||
}
|
||||
|
||||
PyObject* vector_new(PyTypeObject* subtype, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
Py_INCREF(empty_vector);
|
||||
return (PyObject*)empty_vector;
|
||||
}
|
||||
|
||||
long vector_hash(vector_t* self)
|
||||
{
|
||||
todo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* vector_get_item(vector_t* self, Py_ssize_t pos)
|
||||
{
|
||||
if (pos < 0)
|
||||
pos += self->impl.size();
|
||||
if (pos < 0 || pos >= (Py_ssize_t)self->impl.size()) {
|
||||
PyErr_Format(PyExc_IndexError, "Index out of range: %zi", pos);
|
||||
return nullptr;
|
||||
}
|
||||
auto r = self->impl[pos];
|
||||
return r.release();
|
||||
}
|
||||
|
||||
PyObject* vector_subscript(vector_t* self, PyObject* item)
|
||||
{
|
||||
if (PyIndex_Check(item)) {
|
||||
auto i = PyNumber_AsSsize_t(item, PyExc_IndexError);
|
||||
if (i == -1 && PyErr_Occurred())
|
||||
return nullptr;
|
||||
return vector_get_item(self, i);
|
||||
} else if (PySlice_Check(item)) {
|
||||
return todo();
|
||||
} else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"vector indices must be integers, not %.200s",
|
||||
Py_TYPE(item)->tp_name);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* vector_repeat(vector_t* self, Py_ssize_t n)
|
||||
{
|
||||
return todo();
|
||||
}
|
||||
|
||||
int vector_traverse(vector_t* self, visitproc visit, void* arg)
|
||||
{
|
||||
auto result = 0;
|
||||
immer::all_of(self->impl, [&] (auto&& o) {
|
||||
return 0 == (result = [&] {
|
||||
Py_VISIT(o.get());
|
||||
return 0;
|
||||
}());
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject* vector_richcompare(PyObject* v, PyObject* w, int op)
|
||||
{
|
||||
return todo();
|
||||
}
|
||||
|
||||
PyObject* vector_iter(PyObject* self)
|
||||
{
|
||||
return todo();
|
||||
}
|
||||
|
||||
PyMethodDef vector_methods[] =
|
||||
{
|
||||
{"append", (PyCFunction)vector_append, METH_O, "Appends an element"},
|
||||
{"set", (PyCFunction)vector_set, METH_VARARGS, "Inserts an element at the specified position"},
|
||||
{"extend", (PyCFunction)vector_extend, METH_O|METH_COEXIST, "Extend"},
|
||||
{"tolist", (PyCFunction)vector_to_list, METH_NOARGS, "Convert to list"},
|
||||
{0}
|
||||
};
|
||||
|
||||
PyMemberDef vector_members[] =
|
||||
{
|
||||
{0} /* sentinel */
|
||||
};
|
||||
|
||||
PySequenceMethods vector_sequence_methods =
|
||||
{
|
||||
(lenfunc)vector_len, /* sq_length */
|
||||
(binaryfunc)vector_extend, /* sq_concat */
|
||||
(ssizeargfunc)vector_repeat, /* sq_repeat */
|
||||
(ssizeargfunc)vector_get_item, /* sq_item */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
0, /* sq_contains */
|
||||
0, /* sq_inplace_concat */
|
||||
0, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
PyMappingMethods vector_mapping_methods =
|
||||
{
|
||||
(lenfunc)vector_len,
|
||||
(binaryfunc)vector_subscript,
|
||||
0
|
||||
};
|
||||
|
||||
PyTypeObject vector_t::type =
|
||||
{
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"immer.Vector", /* tp_name */
|
||||
sizeof(vector_t), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
(destructor)vector_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
(reprfunc)vector_repr, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
&vector_sequence_methods, /* tp_as_sequence */
|
||||
&vector_mapping_methods, /* tp_as_mapping */
|
||||
(hashfunc)vector_hash, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||
"", /* tp_doc */
|
||||
(traverseproc)vector_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
vector_richcompare, /* tp_richcompare */
|
||||
offsetof(vector_t, in_weakreflist), /* tp_weaklistoffset */
|
||||
vector_iter, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
vector_methods, /* tp_methods */
|
||||
vector_members, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
vector_new, /* tp_new */
|
||||
};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
struct PyModuleDef module_def =
|
||||
{
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"immer_python_module", /* m_name */
|
||||
"", /* m_doc */
|
||||
-1, /* m_size */
|
||||
/module_methods, /* m_methods */
|
||||
0, /* m_reload */
|
||||
0, /* m_traverse */
|
||||
0, /* m_clear */
|
||||
0, /* m_free */
|
||||
};
|
||||
#endif
|
||||
|
||||
PyMethodDef module_methods[] = {
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
PyObject* module_init()
|
||||
{
|
||||
if (PyType_Ready(&vector_t::type) < 0)
|
||||
return nullptr;
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
auto m = PyModule_Create(&module_def);
|
||||
#else
|
||||
auto m = Py_InitModule3("immer_python_module", module_methods, "");
|
||||
#endif
|
||||
if (!m)
|
||||
return nullptr;
|
||||
|
||||
if (!empty_vector)
|
||||
empty_vector = make_vector();
|
||||
|
||||
Py_INCREF(&vector_t::type);
|
||||
PyModule_AddObject(m, "Vector", (PyObject*) &vector_t::type);
|
||||
return m;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
extern "C" {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyMODINIT_FUNC PyInit_immer_python_module()
|
||||
{
|
||||
return module_init();
|
||||
}
|
||||
#else
|
||||
PyMODINIT_FUNC initimmer_python_module()
|
||||
{
|
||||
module_init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue