| /* |
| pybind/complex.h: Complex number support |
| |
| Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> |
| |
| All rights reserved. Use of this source code is governed by a |
| BSD-style license that can be found in the LICENSE file. |
| */ |
| |
| #pragma once |
| |
| #include <pybind/pybind.h> |
| #include <map> |
| #include <iostream> |
| |
| |
| #if defined(_MSC_VER) |
| #pragma warning(push) |
| #pragma warning(disable: 4127) // warning C4127: Conditional expression is constant |
| #endif |
| |
| NAMESPACE_BEGIN(pybind) |
| NAMESPACE_BEGIN(detail) |
| |
| template <typename Value> struct type_caster<std::vector<Value>> { |
| typedef std::vector<Value> type; |
| typedef type_caster<Value> value_conv; |
| public: |
| bool load(PyObject *src, bool convert) { |
| if (!PyList_Check(src)) |
| return false; |
| size_t size = (size_t) PyList_GET_SIZE(src); |
| value.reserve(size); |
| value.clear(); |
| for (size_t i=0; i<size; ++i) { |
| value_conv conv; |
| if (!conv.load(PyList_GetItem(src, (ssize_t) i), convert)) |
| return false; |
| value.push_back((Value) conv); |
| } |
| return true; |
| } |
| |
| static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) { |
| PyObject *list = PyList_New(src.size()); |
| size_t index = 0; |
| for (auto const &value: src) { |
| PyObject *value_ = value_conv::cast(value, policy, parent); |
| if (!value_) { |
| Py_DECREF(list); |
| return nullptr; |
| } |
| PyList_SetItem(list, index++, value_); |
| } |
| return list; |
| } |
| PYBIND_TYPE_CASTER(type, "list<" + value_conv::name() + ">"); |
| }; |
| |
| template <typename Key, typename Value> struct type_caster<std::map<Key, Value>> { |
| public: |
| typedef std::map<Key, Value> type; |
| typedef type_caster<Key> key_conv; |
| typedef type_caster<Value> value_conv; |
| |
| bool load(PyObject *src, bool convert) { |
| if (!PyDict_Check(src)) |
| return false; |
| |
| value.clear(); |
| PyObject *key_, *value_; |
| ssize_t pos = 0; |
| key_conv kconv; |
| value_conv vconv; |
| while (PyDict_Next(src, &pos, &key_, &value_)) { |
| if (!kconv.load(key_, convert) || !vconv.load(value_, convert)) |
| return false; |
| value[kconv] = vconv; |
| } |
| return true; |
| } |
| |
| static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) { |
| PyObject *dict = PyDict_New(); |
| for (auto const &kv: src) { |
| PyObject *key = key_conv::cast(kv.first, policy, parent); |
| PyObject *value = value_conv::cast(kv.second, policy, parent); |
| if (!key || !value || PyDict_SetItem(dict, key, value) < 0) { |
| Py_XDECREF(key); |
| Py_XDECREF(value); |
| Py_DECREF(dict); |
| return nullptr; |
| } |
| Py_DECREF(key); |
| Py_DECREF(value); |
| } |
| return dict; |
| } |
| PYBIND_TYPE_CASTER(type, "dict<" + key_conv::name() + ", " + value_conv::name() + ">"); |
| }; |
| |
| inline std::ostream &operator<<(std::ostream &os, const object &obj) { os << (const char *) obj.str(); return os; } |
| |
| NAMESPACE_END(detail) |
| NAMESPACE_END(pybind) |
| |
| #if defined(_MSC_VER) |
| #pragma warning(pop) |
| #endif |