cast.h 20.2 KB
Newer Older
Wenzel Jakob's avatar
Wenzel Jakob committed
1
/*
2
    pybind11/cast.h: Partial template specializations to cast between
Wenzel Jakob's avatar
Wenzel Jakob committed
3
4
5
6
7
8
9
10
    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 "pytypes.h"
#include "typeid.h"
15
#include "descr.h"
Wenzel Jakob's avatar
Wenzel Jakob committed
16
#include <array>
Wenzel Jakob's avatar
Wenzel Jakob committed
17
#include <limits>
Wenzel Jakob's avatar
Wenzel Jakob committed
18

19
NAMESPACE_BEGIN(pybind11)
Wenzel Jakob's avatar
Wenzel Jakob committed
20
21
NAMESPACE_BEGIN(detail)

22
class type_caster_custom {
Wenzel Jakob's avatar
Wenzel Jakob committed
23
public:
24
    PYBIND11_NOINLINE type_caster_custom(const std::type_info *type_info) {
25
        auto & registered_types = get_internals().registered_types;
26
        auto it = registered_types.find(type_info);
27
        if (it != registered_types.end()) {
Wenzel Jakob's avatar
Wenzel Jakob committed
28
            typeinfo = &it->second;
29
30
31
32
33
34
35
36
37
38
39
        } else {
            /* Unknown type?! Since std::type_info* often varies across
               module boundaries, the following does an explicit check */
            for (auto const &type : registered_types) {
                if (strcmp(type.first->name(), type_info->name()) == 0) {
                    registered_types[type_info] = type.second;
                    typeinfo = &type.second;
                    break;
                }
            }
        }
Wenzel Jakob's avatar
Wenzel Jakob committed
40
41
    }

42
    PYBIND11_NOINLINE bool load(PyObject *src, bool convert) {
Wenzel Jakob's avatar
Wenzel Jakob committed
43
44
45
        if (src == nullptr || typeinfo == nullptr)
            return false;
        if (PyType_IsSubtype(Py_TYPE(src), typeinfo->type)) {
46
            value = ((instance<void> *) src)->value;
Wenzel Jakob's avatar
Wenzel Jakob committed
47
48
49
50
51
52
53
54
55
56
57
58
            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;
    }

59
60
61
    PYBIND11_NOINLINE static PyObject *cast(const void *_src, return_value_policy policy, PyObject *parent,
                                            const std::type_info *type_info, void *(*copy_constructor)(const void *)) {
        void *src = const_cast<void *>(_src);
Wenzel Jakob's avatar
Wenzel Jakob committed
62
63
64
65
66
        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
67
68
        bool dont_cache = policy == return_value_policy::reference_internal &&
                          parent && ((instance<void> *) parent)->value == (void *) src;
Wenzel Jakob's avatar
Wenzel Jakob committed
69
70
71
72
73
74
75
        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;
        }
76
        auto it = internals.registered_types.find(type_info);
Wenzel Jakob's avatar
Wenzel Jakob committed
77
        if (it == internals.registered_types.end()) {
78
79
80
            std::string tname = type_info->name();
            detail::clean_type_id(tname);
            std::string msg = "Unregistered type : " + tname;
Wenzel Jakob's avatar
Wenzel Jakob committed
81
82
83
            PyErr_SetString(PyExc_TypeError, msg.c_str());
            return nullptr;
        }
84
85
        auto &reg_type = it->second;
        instance<void> *inst = (instance<void> *) PyType_GenericAlloc(reg_type.type, 0);
Wenzel Jakob's avatar
Wenzel Jakob committed
86
87
88
89
90
91
        inst->value = src;
        inst->owned = true;
        inst->parent = nullptr;
        if (policy == return_value_policy::automatic)
            policy = return_value_policy::take_ownership;
        if (policy == return_value_policy::copy) {
92
93
94
            inst->value = copy_constructor(inst->value);
            if (inst->value == nullptr)
                throw cast_error("return_value_policy = copy, but the object is non-copyable!");
Wenzel Jakob's avatar
Wenzel Jakob committed
95
96
97
98
99
100
101
        } 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);
        }
102
103
104
105
106
        PyObject *inst_pyobj = (PyObject *) inst;
        reg_type.init_holder(inst_pyobj);
        if (!dont_cache)
            internals.registered_instances[inst->value] = inst_pyobj;
        return inst_pyobj;
Wenzel Jakob's avatar
Wenzel Jakob committed
107
108
109
110
    }

protected:
    const type_info *typeinfo = nullptr;
111
    void *value = nullptr;
Wenzel Jakob's avatar
Wenzel Jakob committed
112
113
114
    object temp;
};

115
/// Generic type caster for objects stored on the heap
Wenzel Jakob's avatar
Wenzel Jakob committed
116
template <typename type, typename Enable = void> class type_caster : public type_caster_custom {
117
public:
118
    static PYBIND11_DESCR name() { return type_descr(_<type>()); }
119
120
121
122
123
124
125
126
127
128
129
130
131
132

    type_caster() : type_caster_custom(&typeid(type)) { }

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

    static PyObject *cast(const type *src, return_value_policy policy, PyObject *parent) {
        return type_caster_custom::cast(src, policy, parent, &typeid(type), &copy_constructor);
    }

    operator type*() { return (type *) value; }
Wenzel Jakob's avatar
Wenzel Jakob committed
133
    operator type&() { return *((type *) value); }
134
135
136
protected:
    template <typename T = type, typename std::enable_if<std::is_copy_constructible<T>::value, int>::type = 0>
    static void *copy_constructor(const void *arg) {
Wenzel Jakob's avatar
Wenzel Jakob committed
137
        return new type(*((const type *)arg));
138
139
140
141
142
    }
    template <typename T = type, typename std::enable_if<!std::is_copy_constructible<T>::value, int>::type = 0>
    static void *copy_constructor(const void *) { return nullptr; }
};

143
#define PYBIND11_TYPE_CASTER(type, py_name) \
Wenzel Jakob's avatar
Wenzel Jakob committed
144
145
146
    protected: \
        type value; \
    public: \
147
        static PYBIND11_DESCR name() { return type_descr(py_name); } \
Wenzel Jakob's avatar
Wenzel Jakob committed
148
149
150
151
        static PyObject *cast(const type *src, return_value_policy policy, PyObject *parent) { \
            return cast(*src, policy, parent); \
        } \
        operator type*() { return &value; } \
Wenzel Jakob's avatar
Wenzel Jakob committed
152
        operator type&() { return value; }
Wenzel Jakob's avatar
Wenzel Jakob committed
153

154
155
156
157
158
159
160
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \
    namespace pybind11 { namespace detail { \
    template <typename type> class type_caster<holder_type> \
        : public type_caster_holder<type, holder_type> { }; \
    }}


Wenzel Jakob's avatar
Wenzel Jakob committed
161
162
163
164
165
166
167
168
template <typename T>
struct type_caster<
    T, typename std::enable_if<std::is_integral<T>::value ||
                               std::is_floating_point<T>::value>::type> {
    typedef typename std::conditional<sizeof(T) <= sizeof(long), long, long long>::type _py_type_0;
    typedef typename std::conditional<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>::type _py_type_1;
    typedef typename std::conditional<std::is_floating_point<T>::value, double, _py_type_1>::type py_type;
public:
Wenzel Jakob's avatar
Wenzel Jakob committed
169

Wenzel Jakob's avatar
Wenzel Jakob committed
170
171
    bool load(PyObject *src, bool) {
        py_type py_value;
Wenzel Jakob's avatar
Wenzel Jakob committed
172

Wenzel Jakob's avatar
Wenzel Jakob committed
173
174
175
176
177
178
179
180
181
        if (std::is_floating_point<T>::value) {
            py_value = (py_type) PyFloat_AsDouble(src);
        } else if (sizeof(T) <= sizeof(long)) {
            if (std::is_signed<T>::value)
                py_value = (py_type) PyLong_AsLong(src);
            else
                py_value = (py_type) PyLong_AsUnsignedLong(src);
        } else {
            if (std::is_signed<T>::value)
182
                py_value = (py_type) PYBIND11_LONG_AS_LONGLONG(src);
Wenzel Jakob's avatar
Wenzel Jakob committed
183
            else
184
                py_value = (py_type) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(src);
Wenzel Jakob's avatar
Wenzel Jakob committed
185
186
187
188
189
190
191
192
193
        }

        if ((py_value == (py_type) -1 && PyErr_Occurred()) ||
            (std::is_integral<T>::value && sizeof(py_type) != sizeof(T) &&
               (py_value < (py_type) std::numeric_limits<T>::min() ||
                py_value > (py_type) std::numeric_limits<T>::max()))) {
            PyErr_Clear();
            return false;
        }
Wenzel Jakob's avatar
Wenzel Jakob committed
194

Wenzel Jakob's avatar
Wenzel Jakob committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        value = (T) py_value;
        return true;
    }

    static PyObject *cast(T src, return_value_policy /* policy */, PyObject * /* parent */) {
        if (std::is_floating_point<T>::value) {
            return PyFloat_FromDouble((double) src);
        } else if (sizeof(T) <= sizeof(long)) {
            if (std::is_signed<T>::value)
                return PyLong_FromLong((long) src);
            else
                return PyLong_FromUnsignedLong((unsigned long) src);
        } else {
            if (std::is_signed<T>::value)
                return PyLong_FromLongLong((long long) src);
            else
                return PyLong_FromUnsignedLongLong((unsigned long long) src);
        }
    }

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

219
220
221
222
    template <typename T2 = T, typename std::enable_if<std::is_integral<T2>::value, int>::type = 0>
    static PYBIND11_DESCR name() { return type_descr(_("int")); }
    template <typename T2 = T, typename std::enable_if<!std::is_integral<T2>::value, int>::type = 0>
    static PYBIND11_DESCR name() { return type_descr(_("float")); }
Wenzel Jakob's avatar
Wenzel Jakob committed
223
224
225
226
227
228
229

    operator T*() { return &value; }
    operator T&() { return value; }

protected:
    T value;
};
Wenzel Jakob's avatar
Wenzel Jakob committed
230

231
template <> class type_caster<void_type> {
Wenzel Jakob's avatar
Wenzel Jakob committed
232
public:
233
    bool load(PyObject *, bool) { return false; }
234
    static PyObject *cast(void_type, return_value_policy /* policy */, PyObject * /* parent */) {
Wenzel Jakob's avatar
Wenzel Jakob committed
235
236
237
        Py_INCREF(Py_None);
        return Py_None;
    }
238
    PYBIND11_TYPE_CASTER(void_type, _("NoneType"));
Wenzel Jakob's avatar
Wenzel Jakob committed
239
240
};

Wenzel Jakob's avatar
Wenzel Jakob committed
241
242
template <> class type_caster<void> : public type_caster<void_type> { };
template <> class type_caster<std::nullptr_t> : public type_caster<void_type> { };
243

Wenzel Jakob's avatar
Wenzel Jakob committed
244
245
246
247
248
249
250
251
252
253
254
255
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;
    }
256
    PYBIND11_TYPE_CASTER(bool, _("bool"));
Wenzel Jakob's avatar
Wenzel Jakob committed
257
258
259
260
261
};

template <> class type_caster<std::string> {
public:
    bool load(PyObject *src, bool) {
262
263
264
265
266
267
268
269
270
271
272
273
        object temp;
        PyObject *load_src = src;
        if (PyUnicode_Check(src)) {
            temp = object(PyUnicode_AsUTF8String(src), false);
            if (!temp) { PyErr_Clear(); return false; }  // UnicodeEncodeError
            load_src = temp.ptr();
        }
        char *buffer;
        ssize_t length;
        int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(load_src, &buffer, &length);
        if (err == -1) { PyErr_Clear(); return false; }  // TypeError
        value = std::string(buffer, length);
Wenzel Jakob's avatar
Wenzel Jakob committed
274
275
        return true;
    }
276

Wenzel Jakob's avatar
Wenzel Jakob committed
277
    static PyObject *cast(const std::string &src, return_value_policy /* policy */, PyObject * /* parent */) {
278
        return PyUnicode_FromStringAndSize(src.c_str(), src.length());
Wenzel Jakob's avatar
Wenzel Jakob committed
279
    }
280
281

    PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
Wenzel Jakob's avatar
Wenzel Jakob committed
282
283
284
285
286
};

template <> class type_caster<char> {
public:
    bool load(PyObject *src, bool) {
287
288
289
290
291
292
293
294
295
296
        object temp;
        PyObject *load_src = src;
        if (PyUnicode_Check(src)) {
            temp = object(PyUnicode_AsUTF8String(src), false);
            if (!temp) { PyErr_Clear(); return false; }  // UnicodeEncodeError
            load_src = temp.ptr();
        }
        const char *ptr = PYBIND11_BYTES_AS_STRING(load_src);
        if (!ptr) { PyErr_Clear(); return false; }  // TypeError
        value = std::string(ptr);
Wenzel Jakob's avatar
Wenzel Jakob committed
297
298
299
300
301
302
303
304
305
306
307
308
        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);
    }

309
310
    operator char*() { return (char *) value.c_str(); }
    operator char() { if (value.length() > 0) return value[0]; else return '\0'; }
311
312

    static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
Wenzel Jakob's avatar
Wenzel Jakob committed
313
protected:
314
    std::string value;
Wenzel Jakob's avatar
Wenzel Jakob committed
315
316
317
318
319
320
321
322
};

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;
323
        if (!first.load(PyTuple_GET_ITEM(src, 0), convert))
Wenzel Jakob's avatar
Wenzel Jakob committed
324
            return false;
325
        return second.load(PyTuple_GET_ITEM(src, 1), convert);
Wenzel Jakob's avatar
Wenzel Jakob committed
326
327
328
    }

    static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent) {
329
330
331
        object o1(type_caster<typename decay<T1>::type>::cast(src.first, policy, parent), false);
        object o2(type_caster<typename decay<T2>::type>::cast(src.second, policy, parent), false);
        if (!o1 || !o2)
Wenzel Jakob's avatar
Wenzel Jakob committed
332
333
            return nullptr;
        PyObject *tuple = PyTuple_New(2);
334
335
        if (!tuple)
            return nullptr;
336
337
        PyTuple_SET_ITEM(tuple, 0, o1.release());
        PyTuple_SET_ITEM(tuple, 1, o2.release());
Wenzel Jakob's avatar
Wenzel Jakob committed
338
339
340
        return tuple;
    }

341
342
343
344
    static PYBIND11_DESCR name() {
        return type_descr(
            _("(") + type_caster<typename decay<T1>::type>::name() +
            _(", ") + type_caster<typename decay<T2>::type>::name() + _(")"));
Wenzel Jakob's avatar
Wenzel Jakob committed
345
346
347
348
349
350
    }

    operator type() {
        return type(first, second);
    }
protected:
351
352
    type_caster<typename decay<T1>::type> first;
    type_caster<typename decay<T2>::type> second;
Wenzel Jakob's avatar
Wenzel Jakob committed
353
354
};

355
template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
Wenzel Jakob's avatar
Wenzel Jakob committed
356
357
358
359
360
    typedef std::tuple<Tuple...> type;
public:
    enum { size = sizeof...(Tuple) };

    bool load(PyObject *src, bool convert) {
Wenzel Jakob's avatar
Wenzel Jakob committed
361
        return load(src, convert, typename make_index_sequence<sizeof...(Tuple)>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
362
363
364
    }

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

368
369
370
371
372
    static PYBIND11_DESCR name() {
        return type_descr(
               _("(") +
               detail::concat(type_caster<typename decay<Tuple>::type>::name()...) +
               _(")"));
Wenzel Jakob's avatar
Wenzel Jakob committed
373
374
    }

375
376
    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
377
378
    }

379
    template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, void_type>::type call(Func &&f) {
380
        call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
381
        return void_type();
Wenzel Jakob's avatar
Wenzel Jakob committed
382
383
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
384
    operator type() {
Wenzel Jakob's avatar
Wenzel Jakob committed
385
        return cast(typename make_index_sequence<sizeof...(Tuple)>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
386
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
387

Wenzel Jakob's avatar
Wenzel Jakob committed
388
protected:
389
    template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
390
391
392
393
        return f((Tuple) std::get<Index>(value)...);
    }

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

Wenzel Jakob's avatar
Wenzel Jakob committed
397
    template <size_t ... Indices> bool load(PyObject *src, bool convert, index_sequence<Indices...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
398
399
400
401
402
        if (!PyTuple_Check(src))
            return false;
        if (PyTuple_Size(src) != size)
            return false;
        std::array<bool, size> results {{
403
            (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
404
        }};
405
        (void) convert; /* avoid a warning when the tuple is empty */
Wenzel Jakob's avatar
Wenzel Jakob committed
406
407
408
409
410
411
412
        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
413
    template <size_t ... Indices> static PyObject *cast(const type &src, return_value_policy policy, PyObject *parent, index_sequence<Indices...>) {
414
415
        std::array<object, size> results {{
            object(type_caster<typename decay<Tuple>::type>::cast(std::get<Indices>(src), policy, parent), false)...
Wenzel Jakob's avatar
Wenzel Jakob committed
416
        }};
417
418
419
420
421
        for (const auto & result : results)
            if (!result)
                return nullptr;
        PyObject *tuple = PyTuple_New(size);
        if (!tuple)
Wenzel Jakob's avatar
Wenzel Jakob committed
422
            return nullptr;
423
424
        int counter = 0;
        for (auto & result : results)
425
            PyTuple_SET_ITEM(tuple, counter++, result.release());
426
        return tuple;
Wenzel Jakob's avatar
Wenzel Jakob committed
427
428
429
    }

protected:
430
    std::tuple<type_caster<typename decay<Tuple>::type>...> value;
Wenzel Jakob's avatar
Wenzel Jakob committed
431
432
433
434
435
436
};

/// 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;
437
438
439
440
441
442
443
444
445
446
447
448

    template <typename T = holder_type,
              typename std::enable_if<std::is_same<std::shared_ptr<type>, T>::value, int>::type = 0>
    bool load(PyObject *src, bool convert) {
        if (!parent::load(src, convert))
            return false;
        holder = holder_type(((type *) parent::value)->shared_from_this());
        return true;
    }

    template <typename T = holder_type,
              typename std::enable_if<!std::is_same<std::shared_ptr<type>, T>::value, int>::type = 0>
Wenzel Jakob's avatar
Wenzel Jakob committed
449
450
451
    bool load(PyObject *src, bool convert) {
        if (!parent::load(src, convert))
            return false;
452
        holder = holder_type((type *) parent::value);
Wenzel Jakob's avatar
Wenzel Jakob committed
453
454
        return true;
    }
455

Wenzel Jakob's avatar
Wenzel Jakob committed
456
457
458
459
    explicit operator type*() { return this->value; }
    explicit operator type&() { return *(this->value); }
    explicit operator holder_type&() { return holder; }
    explicit operator holder_type*() { return &holder; }
460
461
462
463
464
465

    using type_caster<type>::cast;
    static PyObject *cast(const holder_type &src, return_value_policy policy, PyObject *parent) {
        return type_caster<type>::cast(src.get(), policy, parent);
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
466
467
468
469
protected:
    holder_type holder;
};

470
471
472
template <typename T> struct handle_type_name { static PYBIND11_DESCR name() { return _<T>(); } };
template <> struct handle_type_name<bytes> { static PYBIND11_DESCR name() { return _(PYBIND11_BYTES_NAME); } };

473
474
template <typename type>
struct type_caster<type, typename std::enable_if<std::is_base_of<handle, type>::value>::type> {
Wenzel Jakob's avatar
Wenzel Jakob committed
475
public:
476
477
478
479
480
481
    template <typename T = type, typename std::enable_if<std::is_same<T, handle>::value, int>::type = 0>
    bool load(PyObject *src, bool /* convert */) { value = handle(src); return value.check(); }

    template <typename T = type, typename std::enable_if<!std::is_same<T, handle>::value, int>::type = 0>
    bool load(PyObject *src, bool /* convert */) { value = type(src, true); return value.check(); }

Wenzel Jakob's avatar
Wenzel Jakob committed
482
    static PyObject *cast(const handle &src, return_value_policy /* policy */, PyObject * /* parent */) {
483
        src.inc_ref(); return (PyObject *) src.ptr();
Wenzel Jakob's avatar
Wenzel Jakob committed
484
    }
485
    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name());
Wenzel Jakob's avatar
Wenzel Jakob committed
486
487
488
489
490
};

NAMESPACE_END(detail)

template <typename T> inline T cast(PyObject *object) {
Wenzel Jakob's avatar
Wenzel Jakob committed
491
    detail::type_caster<typename detail::decay<T>::type> conv;
Wenzel Jakob's avatar
Wenzel Jakob committed
492
493
494
495
496
497
498
499
    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
500
    return object(detail::type_caster<typename detail::decay<T>::type>::cast(value, policy, parent), false);
Wenzel Jakob's avatar
Wenzel Jakob committed
501
502
}

503
504
template <typename T> inline T handle::cast() const { return pybind11::cast<T>(m_ptr); }
template <> inline void handle::cast() const { return; }
Wenzel Jakob's avatar
Wenzel Jakob committed
505

506
template <typename... Args> inline object handle::call(Args&&... args_) const {
Wenzel Jakob's avatar
Wenzel Jakob committed
507
    const size_t size = sizeof...(Args);
508
509
510
    std::array<object, size> args{
        { object(detail::type_caster<typename detail::decay<Args>::type>::cast(
            std::forward<Args>(args_), return_value_policy::reference, nullptr), false)... }
Wenzel Jakob's avatar
Wenzel Jakob committed
511
    };
512
513
514
515
516
    for (const auto & result : args)
        if (!result)
            throw cast_error("handle::call(): unable to convert input arguments to Python objects");
    object tuple(PyTuple_New(size), false);
    if (!tuple)
517
        throw cast_error("handle::call(): unable to allocate tuple");
Wenzel Jakob's avatar
Wenzel Jakob committed
518
    int counter = 0;
519
    for (auto & result : args)
520
        PyTuple_SET_ITEM(tuple.ptr(), counter++, result.release());
521
    PyObject *result = PyObject_CallObject(m_ptr, tuple.ptr());
522
523
    if (result == nullptr && PyErr_Occurred())
        throw error_already_set();
Wenzel Jakob's avatar
Wenzel Jakob committed
524
525
526
    return object(result, false);
}

527
NAMESPACE_END(pybind11)