cast.h 21.4 KB
Newer Older
Wenzel Jakob's avatar
Wenzel Jakob committed
1
2
3
4
5
6
7
8
9
10
/*
    pybind/cast.h: Partial template specializations to cast between
    C++ and Python types

    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.
*/

11
#pragma once
Wenzel Jakob's avatar
Wenzel Jakob committed
12

13
14
#include <pybind/pytypes.h>
#include <pybind/typeid.h>
Wenzel Jakob's avatar
Wenzel Jakob committed
15
#include <array>
Wenzel Jakob's avatar
Wenzel Jakob committed
16
#include <limits>
Wenzel Jakob's avatar
Wenzel Jakob committed
17
18
19
20

NAMESPACE_BEGIN(pybind)
NAMESPACE_BEGIN(detail)

21
22
23
24
25
26
#if defined(_MSC_VER)
#define NOINLINE __declspec(noinline)
#else
#define NOINLINE __attribute__ ((noinline))
#endif

27
28
29
30
31
32
#if PY_MAJOR_VERSION >= 3
#define PYBIND_AS_STRING PyBytes_AsString
#else
#define PYBIND_AS_STRING PyString_AsString
#endif

33
/** Linked list descriptor type for function signatures (produces smaller binaries
34
    compared to a previous solution using std::string and operator +=) */
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
class descr {
public:
    struct entry {
        const std::type_info *type = nullptr;
        const char *str = nullptr;
        entry *next = nullptr;
        entry(const std::type_info *type) : type(type) { }
        entry(const char *str) : str(str) { }
    };

    descr() { }
    descr(descr &&d) : first(d.first), last(d.last) { d.first = d.last = nullptr; }
    NOINLINE descr(const char *str) { first = last = new entry { str }; }
    NOINLINE descr(const std::type_info &type) { first = last = new entry { &type }; }

    NOINLINE void operator+(const char *str) {
        entry *next = new entry { str };
        last->next = next;
        last = next;
    }

    NOINLINE void operator+(const std::type_info *type) {
        entry *next = new entry { type };
        last->next = next;
        last = next;
    }

    NOINLINE void operator+=(descr &&other) {
        last->next = other.first;
        while (last->next)
            last = last->next;
        other.first = other.last = nullptr;
    }

    NOINLINE friend descr operator+(descr &&l, descr &&r) {
        descr result(std::move(l));
        result += std::move(r);
        return result;
    }

    NOINLINE std::string str() const {
        std::string result;
        auto const& registered_types = get_internals().registered_types;
        for (entry *it = first; it != nullptr; it = it->next) {
            if (it->type) {
                auto it2 = registered_types.find(it->type);
                if (it2 != registered_types.end()) {
                    result += it2->second.type->tp_name;
                } else {
                    std::string tname(it->type->name());
                    detail::clean_type_id(tname);
                    result += tname;
                }
            } else {
                result += it->str;
            }
        }
        return result;
    }

    NOINLINE ~descr() {
        while (first) {
            entry *tmp = first->next;
            delete first;
            first = tmp;
        }
    }

    entry *first = nullptr;
    entry *last = nullptr;
};

#undef NOINLINE

Wenzel Jakob's avatar
Wenzel Jakob committed
109
110
111
112
113
/// Generic type caster for objects stored on the heap
template <typename type> class type_caster {
public:
    typedef instance<type> instance_type;

Wenzel Jakob's avatar
Wenzel Jakob committed
114
    static descr name() { return typeid(type); }
Wenzel Jakob's avatar
Wenzel Jakob committed
115
116
117

    type_caster() {
        auto const& registered_types = get_internals().registered_types;
118
        auto it = registered_types.find(&typeid(type));
Wenzel Jakob's avatar
Wenzel Jakob committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
        if (it != registered_types.end())
            typeinfo = &it->second;
    }

    bool load(PyObject *src, bool convert) {
        if (src == nullptr || typeinfo == nullptr)
            return false;
        if (PyType_IsSubtype(Py_TYPE(src), typeinfo->type)) {
            value = ((instance_type *) src)->value;
            return true;
        }
        if (convert) {
            for (auto &converter : typeinfo->implicit_conversions) {
                temp = object(converter(src, typeinfo->type), false);
                if (load(temp.ptr(), false))
                    return true;
            }
        }
        return false;
    }

    static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
        if (policy == return_value_policy::automatic)
            policy = return_value_policy::copy;
        return cast(&src, policy, parent);
    }

    static PyObject *cast(const type *_src, return_value_policy policy, PyObject *parent) {
        type *src = const_cast<type *>(_src);
        if (src == nullptr) {
            Py_INCREF(Py_None);
            return Py_None;
        }
        // avoid an issue with internal references matching their parent's address
Wenzel Jakob's avatar
Wenzel Jakob committed
153
154
        bool dont_cache = policy == return_value_policy::reference_internal &&
                          parent && ((instance<void> *) parent)->value == (void *) src;
Wenzel Jakob's avatar
Wenzel Jakob committed
155
156
157
158
159
160
161
        auto& internals = get_internals();
        auto it_instance = internals.registered_instances.find(src);
        if (it_instance != internals.registered_instances.end() && !dont_cache) {
            PyObject *inst = it_instance->second;
            Py_INCREF(inst);
            return inst;
        }
162
        auto it = internals.registered_types.find(&typeid(type));
Wenzel Jakob's avatar
Wenzel Jakob committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
        if (it == internals.registered_types.end()) {
            std::string msg = std::string("Unregistered type : ") + type_id<type>();
            PyErr_SetString(PyExc_TypeError, msg.c_str());
            return nullptr;
        }
        auto &type_info = it->second;
        instance_type *inst = (instance_type *) PyType_GenericAlloc(type_info.type, 0);
        inst->value = src;
        inst->owned = true;
        inst->parent = nullptr;
        if (policy == return_value_policy::automatic)
            policy = return_value_policy::take_ownership;
        handle_return_value_policy<type>(inst, policy, parent);
        PyObject *inst_pyobj = (PyObject *) inst;
        type_info.init_holder(inst_pyobj);
        if (!dont_cache)
            internals.registered_instances[inst->value] = inst_pyobj;
        return inst_pyobj;
    }

    template <class T, typename std::enable_if<std::is_copy_constructible<T>::value, int>::type = 0>
    static void handle_return_value_policy(instance<T> *inst, return_value_policy policy, PyObject *parent) {
        if (policy == return_value_policy::copy) {
            inst->value = new T(*(inst->value));
        } else if (policy == return_value_policy::reference) {
            inst->owned = false;
        } else if (policy == return_value_policy::reference_internal) {
            inst->owned = false;
            inst->parent = parent;
            Py_XINCREF(parent);
        }
    }

    template <class T, typename std::enable_if<!std::is_copy_constructible<T>::value, int>::type = 0>
    static void handle_return_value_policy(instance<T> *inst, return_value_policy policy, PyObject *parent) {
        if (policy == return_value_policy::copy) {
            throw cast_error("return_value_policy = copy, but the object is non-copyable!");
        } else if (policy == return_value_policy::reference) {
            inst->owned = false;
        } else if (policy == return_value_policy::reference_internal) {
            inst->owned = false;
            inst->parent = parent;
            Py_XINCREF(parent);
        }
    }

    operator type*() { return value; }
    operator type&() { return *value; }
protected:
    type *value = nullptr;
    const type_info *typeinfo = nullptr;
    object temp;
};

Wenzel Jakob's avatar
Wenzel Jakob committed
217
#define PYBIND_TYPE_CASTER(type, py_name) \
Wenzel Jakob's avatar
Wenzel Jakob committed
218
219
220
    protected: \
        type value; \
    public: \
Wenzel Jakob's avatar
Wenzel Jakob committed
221
        static descr name() { return py_name; } \
Wenzel Jakob's avatar
Wenzel Jakob committed
222
223
224
225
226
227
        static PyObject *cast(const type *src, return_value_policy policy, PyObject *parent) { \
            return cast(*src, policy, parent); \
        } \
        operator type*() { return &value; } \
        operator type&() { return value; } \

Wenzel Jakob's avatar
Wenzel Jakob committed
228
#define PYBIND_TYPE_CASTER_NUMBER(type, py_type, from_type, to_pytype) \
Wenzel Jakob's avatar
Wenzel Jakob committed
229
230
231
    template <> class type_caster<type> { \
    public: \
        bool load(PyObject *src, bool) { \
Wenzel Jakob's avatar
Wenzel Jakob committed
232
233
            py_type py_value = from_type(src); \
            if ((py_value == (py_type) -1 && PyErr_Occurred()) || \
Wenzel Jakob's avatar
Wenzel Jakob committed
234
235
                (std::numeric_limits<type>::is_integer && \
                 sizeof(py_type) != sizeof(type) && \
Wenzel Jakob's avatar
Wenzel Jakob committed
236
237
                 (py_value < (py_type) std::numeric_limits<type>::min() || \
                  py_value > (py_type) std::numeric_limits<type>::max()))) { \
Wenzel Jakob's avatar
Wenzel Jakob committed
238
239
240
                PyErr_Clear(); \
                return false; \
            } \
Wenzel Jakob's avatar
Wenzel Jakob committed
241
            value = (type) py_value; \
Wenzel Jakob's avatar
Wenzel Jakob committed
242
243
244
245
246
            return true; \
        } \
        static PyObject *cast(type src, return_value_policy /* policy */, PyObject * /* parent */) { \
            return to_pytype((py_type) src); \
        } \
Wenzel Jakob's avatar
Wenzel Jakob committed
247
        PYBIND_TYPE_CASTER(type, #type); \
Wenzel Jakob's avatar
Wenzel Jakob committed
248
249
    };

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#if PY_MAJOR_VERSION >= 3
#define PyLong_AsUnsignedLongLong_Fixed PyLong_AsUnsignedLongLong
#define PyLong_AsLongLong_Fixed PyLong_AsLongLong
#else
inline PY_LONG_LONG PyLong_AsLongLong_Fixed(PyObject *o) {
    if (PyInt_Check(o))
        return (PY_LONG_LONG) PyLong_AsLong(o);
    else
        return ::PyLong_AsLongLong(o);
}

inline unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong_Fixed(PyObject *o) {
    if (PyInt_Check(o))
        return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLong(o);
    else
        return ::PyLong_AsUnsignedLongLong(o);
}
#endif

Wenzel Jakob's avatar
Wenzel Jakob committed
269
270
271
272
PYBIND_TYPE_CASTER_NUMBER(int8_t, long, PyLong_AsLong, PyLong_FromLong)
PYBIND_TYPE_CASTER_NUMBER(uint8_t, unsigned long, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong)
PYBIND_TYPE_CASTER_NUMBER(int16_t, long, PyLong_AsLong, PyLong_FromLong)
PYBIND_TYPE_CASTER_NUMBER(uint16_t, unsigned long, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong)
Wenzel Jakob's avatar
Wenzel Jakob committed
273
274
PYBIND_TYPE_CASTER_NUMBER(int32_t, long, PyLong_AsLong, PyLong_FromLong)
PYBIND_TYPE_CASTER_NUMBER(uint32_t, unsigned long, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong)
275
276
PYBIND_TYPE_CASTER_NUMBER(int64_t, PY_LONG_LONG, PyLong_AsLongLong_Fixed, PyLong_FromLongLong)
PYBIND_TYPE_CASTER_NUMBER(uint64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong_Fixed, PyLong_FromUnsignedLongLong)
Wenzel Jakob's avatar
Wenzel Jakob committed
277
278

#if defined(__APPLE__) // size_t/ssize_t are separate types on Mac OS X
279
#if PY_MAJOR_VERSION >= 3
Wenzel Jakob's avatar
Wenzel Jakob committed
280
281
PYBIND_TYPE_CASTER_NUMBER(ssize_t, Py_ssize_t, PyLong_AsSsize_t, PyLong_FromSsize_t)
PYBIND_TYPE_CASTER_NUMBER(size_t, size_t, PyLong_AsSize_t, PyLong_FromSize_t)
282
283
284
285
#else
PYBIND_TYPE_CASTER_NUMBER(ssize_t, PY_LONG_LONG, PyLong_AsLongLong_Fixed, PyLong_FromLongLong)
PYBIND_TYPE_CASTER_NUMBER(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong_Fixed, PyLong_FromUnsignedLongLong)
#endif
Wenzel Jakob's avatar
Wenzel Jakob committed
286
287
#endif

Wenzel Jakob's avatar
Wenzel Jakob committed
288
PYBIND_TYPE_CASTER_NUMBER(float, double, PyFloat_AsDouble, PyFloat_FromDouble)
Wenzel Jakob's avatar
Wenzel Jakob committed
289
PYBIND_TYPE_CASTER_NUMBER(double, double, PyFloat_AsDouble, PyFloat_FromDouble)
Wenzel Jakob's avatar
Wenzel Jakob committed
290

291
template <> class type_caster<void_type> {
Wenzel Jakob's avatar
Wenzel Jakob committed
292
293
public:
    bool load(PyObject *, bool) { return true; }
294
    static PyObject *cast(void_type, return_value_policy /* policy */, PyObject * /* parent */) {
Wenzel Jakob's avatar
Wenzel Jakob committed
295
296
297
        Py_INCREF(Py_None);
        return Py_None;
    }
298
    PYBIND_TYPE_CASTER(void_type, "None");
Wenzel Jakob's avatar
Wenzel Jakob committed
299
300
};

301
302
303
template <> class type_caster<void> : public type_caster<void_type> {
};

Wenzel Jakob's avatar
Wenzel Jakob committed
304
305
306
307
308
309
310
311
312
313
314
315
template <> class type_caster<bool> {
public:
    bool load(PyObject *src, bool) {
        if (src == Py_True) { value = true; return true; }
        else if (src == Py_False) { value = false; return true; }
        else return false;
    }
    static PyObject *cast(bool src, return_value_policy /* policy */, PyObject * /* parent */) {
        PyObject *result = src ? Py_True : Py_False;
        Py_INCREF(result);
        return result;
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
316
    PYBIND_TYPE_CASTER(bool, "bool");
Wenzel Jakob's avatar
Wenzel Jakob committed
317
318
319
320
321
};

template <> class type_caster<std::string> {
public:
    bool load(PyObject *src, bool) {
322
323
#if PY_MAJOR_VERSION < 3
        if (PyString_Check(src)) { value = PyString_AsString(src); return true; }
324
#endif
325
326
327
328
        object temp(PyUnicode_AsUTF8String(src), false);
        const char *ptr = nullptr;
        if (temp)
            ptr = PYBIND_AS_STRING(temp.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
329
        if (!ptr) { PyErr_Clear(); return false; }
330
        value = ptr;
Wenzel Jakob's avatar
Wenzel Jakob committed
331
332
333
334
335
        return true;
    }
    static PyObject *cast(const std::string &src, return_value_policy /* policy */, PyObject * /* parent */) {
        return PyUnicode_FromString(src.c_str());
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
336
    PYBIND_TYPE_CASTER(std::string, "str");
Wenzel Jakob's avatar
Wenzel Jakob committed
337
338
339
340
341
};

template <> class type_caster<char> {
public:
    bool load(PyObject *src, bool) {
342
343
#if PY_MAJOR_VERSION < 3
        if (PyString_Check(src)) { value = PyString_AsString(src); return true; }
344
#endif
345
346
347
348
        object temp(PyUnicode_AsUTF8String(src), false);
        const char *ptr = nullptr;
        if (temp)
            ptr = PYBIND_AS_STRING(temp.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
        if (!ptr) { PyErr_Clear(); return false; }
        value = ptr;
        return true;
    }

    static PyObject *cast(const char *src, return_value_policy /* policy */, PyObject * /* parent */) {
        return PyUnicode_FromString(src);
    }

    static PyObject *cast(char src, return_value_policy /* policy */, PyObject * /* parent */) {
        char str[2] = { src, '\0' };
        return PyUnicode_DecodeLatin1(str, 1, nullptr);
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
363
    static descr name() { return "str"; }
Wenzel Jakob's avatar
Wenzel Jakob committed
364

365
366
    operator char*() { return (char *) value.c_str(); }
    operator char() { if (value.length() > 0) return value[0]; else return '\0'; }
Wenzel Jakob's avatar
Wenzel Jakob committed
367
protected:
368
    std::string value;
Wenzel Jakob's avatar
Wenzel Jakob committed
369
370
371
372
373
374
375
376
377
378
379
380
381
382
};

template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
    typedef std::pair<T1, T2> type;
public:
    bool load(PyObject *src, bool convert) {
        if (!PyTuple_Check(src) || PyTuple_Size(src) != 2)
            return false;
        if (!first.load(PyTuple_GetItem(src, 0), convert))
            return false;
        return second.load(PyTuple_GetItem(src, 1), convert);
    }

    static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
383
384
        PyObject *o1 = type_caster<typename decay<T1>::type>::cast(src.first, policy, parent);
        PyObject *o2 = type_caster<typename decay<T2>::type>::cast(src.second, policy, parent);
Wenzel Jakob's avatar
Wenzel Jakob committed
385
386
387
388
389
390
391
392
393
394
395
        if (!o1 || !o2) {
            Py_XDECREF(o1);
            Py_XDECREF(o2);
            return nullptr;
        }
        PyObject *tuple = PyTuple_New(2);
        PyTuple_SetItem(tuple, 0, o1);
        PyTuple_SetItem(tuple, 1, o2);
        return tuple;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
396
    static descr name() {
397
        class descr result("(");
Wenzel Jakob's avatar
Wenzel Jakob committed
398
        result += std::move(type_caster<typename decay<T1>::type>::name());
399
        result += ", ";
Wenzel Jakob's avatar
Wenzel Jakob committed
400
        result += std::move(type_caster<typename decay<T2>::type>::name());
401
402
        result += ")";
        return result;
Wenzel Jakob's avatar
Wenzel Jakob committed
403
404
405
406
407
408
    }

    operator type() {
        return type(first, second);
    }
protected:
409
410
    type_caster<typename decay<T1>::type> first;
    type_caster<typename decay<T2>::type> second;
Wenzel Jakob's avatar
Wenzel Jakob committed
411
412
};

413
template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
Wenzel Jakob's avatar
Wenzel Jakob committed
414
415
416
417
418
    typedef std::tuple<Tuple...> type;
public:
    enum { size = sizeof...(Tuple) };

    bool load(PyObject *src, bool convert) {
Wenzel Jakob's avatar
Wenzel Jakob committed
419
        return load(src, convert, typename make_index_sequence<sizeof...(Tuple)>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
420
421
422
    }

    static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
Wenzel Jakob's avatar
Wenzel Jakob committed
423
        return cast(src, policy, parent, typename make_index_sequence<size>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
424
425
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
426
427
428
    static descr name(const char **keywords = nullptr, const char **values = nullptr) {
        std::array<class descr, size> names {{
            type_caster<typename decay<Tuple>::type>::name()...
Wenzel Jakob's avatar
Wenzel Jakob committed
429
        }};
430
431
432
433
        class descr result("(");
        for (int i=0; i<size; ++i) {
            if (keywords && keywords[i]) {
                result += keywords[i];
434
435
                result += " : ";
            }
Wenzel Jakob's avatar
Wenzel Jakob committed
436
            result += std::move(names[i]);
437
            if (values && values[i]) {
438
                result += " = ";
439
                result += values[i];
440
            }
441
            if (i+1 < size)
Wenzel Jakob's avatar
Wenzel Jakob committed
442
443
444
445
446
447
                result += ", ";
        }
        result += ")";
        return result;
    }

448
449
    template <typename ReturnValue, typename Func> typename std::enable_if<!std::is_void<ReturnValue>::value, ReturnValue>::type call(Func &&f) {
        return call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
450
451
    }

452
    template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, void_type>::type call(Func &&f) {
453
        call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
454
        return void_type();
Wenzel Jakob's avatar
Wenzel Jakob committed
455
456
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
457
    operator type() {
Wenzel Jakob's avatar
Wenzel Jakob committed
458
        return cast(typename make_index_sequence<sizeof...(Tuple)>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
459
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
460

Wenzel Jakob's avatar
Wenzel Jakob committed
461
protected:
462
    template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
463
464
465
466
        return f((Tuple) std::get<Index>(value)...);
    }

    template <size_t ... Index> type cast(index_sequence<Index...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
467
468
469
        return type((Tuple) std::get<Index>(value)...);
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
470
    template <size_t ... Indices> bool load(PyObject *src, bool convert, index_sequence<Indices...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
471
472
473
474
475
        if (!PyTuple_Check(src))
            return false;
        if (PyTuple_Size(src) != size)
            return false;
        std::array<bool, size> results {{
476
            (PyTuple_GET_ITEM(src, Indices) != nullptr ? std::get<Indices>(value).load(PyTuple_GET_ITEM(src, Indices), convert) : false)...
Wenzel Jakob's avatar
Wenzel Jakob committed
477
        }};
478
        (void) convert; /* avoid a warning when the tuple is empty */
Wenzel Jakob's avatar
Wenzel Jakob committed
479
480
481
482
483
484
485
        for (bool r : results)
            if (!r)
                return false;
        return true;
    }

    /* Implementation: Convert a C++ tuple into a Python tuple */
Wenzel Jakob's avatar
Wenzel Jakob committed
486
    template <size_t ... Indices> static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent, index_sequence<Indices...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
487
        std::array<PyObject *, size> results {{
488
            type_caster<typename decay<Tuple>::type>::cast(std::get<Indices>(src), policy, parent)...
Wenzel Jakob's avatar
Wenzel Jakob committed
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
        }};
        bool success = true;
        for (auto result : results)
            if (result == nullptr)
                success = false;
        if (success) {
            PyObject *tuple = PyTuple_New(size);
            int counter = 0;
            for (auto result : results)
                PyTuple_SetItem(tuple, counter++, result);
            return tuple;
        } else {
            for (auto result : results) {
                Py_XDECREF(result);
            }
            return nullptr;
        }
    }

protected:
509
    std::tuple<type_caster<typename decay<Tuple>::type>...> value;
Wenzel Jakob's avatar
Wenzel Jakob committed
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
};

/// Type caster for holder types like std::shared_ptr, etc.
template <typename type, typename holder_type> class type_caster_holder : public type_caster<type> {
public:
    typedef type_caster<type> parent;
    bool load(PyObject *src, bool convert) {
        if (!parent::load(src, convert))
            return false;
        holder = holder_type(parent::value);
        return true;
    }
    explicit operator type*() { return this->value; }
    explicit operator type&() { return *(this->value); }
    explicit operator holder_type&() { return holder; }
    explicit operator holder_type*() { return &holder; }
protected:
    holder_type holder;
};

template <> class type_caster<handle> {
public:
    bool load(PyObject *src) {
        value = handle(src);
        return true;
    }
    static PyObject *cast(const handle &src, return_value_policy /* policy */, PyObject * /* parent */) {
        src.inc_ref();
        return (PyObject *) src.ptr();
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
540
    PYBIND_TYPE_CASTER(handle, "handle");
Wenzel Jakob's avatar
Wenzel Jakob committed
541
542
};

Wenzel Jakob's avatar
Wenzel Jakob committed
543
#define PYBIND_TYPE_CASTER_PYTYPE(name) \
Wenzel Jakob's avatar
Wenzel Jakob committed
544
545
546
547
548
549
    template <> class type_caster<name> { \
    public: \
        bool load(PyObject *src, bool) { value = name(src, true); return true; } \
        static PyObject *cast(const name &src, return_value_policy /* policy */, PyObject * /* parent */) { \
            src.inc_ref(); return (PyObject *) src.ptr(); \
        } \
Wenzel Jakob's avatar
Wenzel Jakob committed
550
        PYBIND_TYPE_CASTER(name, #name); \
Wenzel Jakob's avatar
Wenzel Jakob committed
551
552
    };

Wenzel Jakob's avatar
Wenzel Jakob committed
553
554
555
556
557
PYBIND_TYPE_CASTER_PYTYPE(object)  PYBIND_TYPE_CASTER_PYTYPE(buffer)
PYBIND_TYPE_CASTER_PYTYPE(capsule) PYBIND_TYPE_CASTER_PYTYPE(dict)
PYBIND_TYPE_CASTER_PYTYPE(float_)  PYBIND_TYPE_CASTER_PYTYPE(int_)
PYBIND_TYPE_CASTER_PYTYPE(list)    PYBIND_TYPE_CASTER_PYTYPE(slice)
PYBIND_TYPE_CASTER_PYTYPE(tuple)   PYBIND_TYPE_CASTER_PYTYPE(function)
Wenzel Jakob's avatar
Wenzel Jakob committed
558
559
560
561

NAMESPACE_END(detail)

template <typename T> inline T cast(PyObject *object) {
Wenzel Jakob's avatar
Wenzel Jakob committed
562
    detail::type_caster<typename detail::decay<T>::type> conv;
Wenzel Jakob's avatar
Wenzel Jakob committed
563
564
565
566
567
568
569
570
    if (!conv.load(object, true))
        throw cast_error("Unable to cast Python object to C++ type");
    return conv;
}

template <typename T> inline object cast(const T &value, return_value_policy policy = return_value_policy::automatic, PyObject *parent = nullptr) {
    if (policy == return_value_policy::automatic)
        policy = std::is_pointer<T>::value ? return_value_policy::take_ownership : return_value_policy::copy;
Wenzel Jakob's avatar
Wenzel Jakob committed
571
    return object(detail::type_caster<typename detail::decay<T>::type>::cast(value, policy, parent), false);
Wenzel Jakob's avatar
Wenzel Jakob committed
572
573
574
}

template <typename T> inline T handle::cast() { return pybind::cast<T>(m_ptr); }
575
template <> inline void handle::cast() { return; }
Wenzel Jakob's avatar
Wenzel Jakob committed
576

577
template <typename... Args> inline object handle::call(Args&&... args_) {
Wenzel Jakob's avatar
Wenzel Jakob committed
578
579
    const size_t size = sizeof...(Args);
    std::array<PyObject *, size> args{
Wenzel Jakob's avatar
Wenzel Jakob committed
580
        { detail::type_caster<typename detail::decay<Args>::type>::cast(
Wenzel Jakob's avatar
Wenzel Jakob committed
581
            std::forward<Args>(args_), return_value_policy::reference, nullptr)... }
Wenzel Jakob's avatar
Wenzel Jakob committed
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
    };
    bool fail = false;
    for (auto result : args)
        if (result == nullptr)
            fail = true;
    if (fail) {
        for (auto result : args) {
            Py_XDECREF(result);
        }
        throw cast_error("handle::call(): unable to convert input arguments to Python objects");
    }
    PyObject *tuple = PyTuple_New(size);
    int counter = 0;
    for (auto result : args)
        PyTuple_SetItem(tuple, counter++, result);
    PyObject *result = PyObject_CallObject(m_ptr, tuple);
    Py_DECREF(tuple);
599
600
    if (result == nullptr && PyErr_Occurred())
        throw error_already_set();
Wenzel Jakob's avatar
Wenzel Jakob committed
601
602
603
604
    return object(result, false);
}

NAMESPACE_END(pybind)