cast.h 22.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)

Wenzel Jakob's avatar
Wenzel Jakob committed
22
23
24
25
26
27
28
29
30
/// Additional type information which does not fit into the PyTypeObject
struct type_info {
    PyTypeObject *type;
    size_t type_size;
    void (*init_holder)(PyObject *, const void *);
    std::vector<PyObject *(*)(PyObject *, PyTypeObject *) > implicit_conversions;
    buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
    void *get_buffer_data = nullptr;
};
31

Wenzel Jakob's avatar
Wenzel Jakob committed
32
33
34
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
PYBIND11_NOINLINE inline internals &get_internals() {
    static internals *internals_ptr = nullptr;
    if (internals_ptr)
        return *internals_ptr;
    handle builtins(PyEval_GetBuiltins());
    capsule caps(builtins["__pybind11__"]);
    if (caps.check()) {
        internals_ptr = caps;
    } else {
        internals_ptr = new internals();
        builtins["__pybind11__"] = capsule(internals_ptr);
    }
    return *internals_ptr;
}

PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
    auto const &type_dict = get_internals().registered_types_py;
    do {
        auto it = type_dict.find(type);
        if (it != type_dict.end())
            return (detail::type_info *) it->second;
        type = type->tp_base;
        if (!type)
            pybind11_fail("pybind11::detail::get_type_info: unable to find type object!");
    } while (true);
}

PYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_info &tp) {
    auto &types = get_internals().registered_types_cpp;

62
63
    auto it = types.find(std::type_index(tp));
    if (it != types.end())
Wenzel Jakob's avatar
Wenzel Jakob committed
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
        return (detail::type_info *) it->second;
    return nullptr;
}

PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp) {
    detail::type_info *type_info = get_type_info(tp);
    return handle(type_info ? ((PyObject *) type_info->type) : nullptr);
}

PYBIND11_NOINLINE inline std::string error_string() {
    std::string errorString;
    PyThreadState *tstate = PyThreadState_GET();
    if (tstate == nullptr)
        return "";

    if (tstate->curexc_type) {
        errorString += (std::string) handle(tstate->curexc_type).str();
        errorString += ": ";
    }
    if (tstate->curexc_value)
        errorString += (std::string) handle(tstate->curexc_value).str();

    return errorString;
}

PYBIND11_NOINLINE inline handle get_object_handle(const void *ptr) {
    auto instances = get_internals().registered_instances;
    auto it = instances.find(ptr);
    if (it == instances.end())
        return handle();
    return handle((PyObject *) it->second);
}

class type_caster_generic {
public:
    PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info)
     : typeinfo(get_type_info(type_info)) { }
Wenzel Jakob's avatar
Wenzel Jakob committed
101

Wenzel Jakob's avatar
Wenzel Jakob committed
102
103
    PYBIND11_NOINLINE bool load(handle src, bool convert) {
        if (!src || !typeinfo)
Wenzel Jakob's avatar
Wenzel Jakob committed
104
            return false;
Wenzel Jakob's avatar
Wenzel Jakob committed
105
106
        if (PyType_IsSubtype(Py_TYPE(src.ptr()), typeinfo->type)) {
            value = ((instance<void> *) src.ptr())->value;
Wenzel Jakob's avatar
Wenzel Jakob committed
107
108
109
110
            return true;
        }
        if (convert) {
            for (auto &converter : typeinfo->implicit_conversions) {
Wenzel Jakob's avatar
Wenzel Jakob committed
111
112
                temp = object(converter(src.ptr(), typeinfo->type), false);
                if (load(temp, false))
Wenzel Jakob's avatar
Wenzel Jakob committed
113
114
115
116
117
118
                    return true;
            }
        }
        return false;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
119
120
121
122
    PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent,
                                         const std::type_info *type_info,
                                         void *(*copy_constructor)(const void *),
                                         const void *existing_holder = nullptr) {
123
        void *src = const_cast<void *>(_src);
Wenzel Jakob's avatar
Wenzel Jakob committed
124
125
126
        if (src == nullptr)
            return handle(Py_None).inc_ref();

Wenzel Jakob's avatar
Wenzel Jakob committed
127
        // avoid an issue with internal references matching their parent's address
Wenzel Jakob's avatar
Wenzel Jakob committed
128
        bool dont_cache = policy == return_value_policy::reference_internal &&
Wenzel Jakob's avatar
Wenzel Jakob committed
129
130
                          parent && ((instance<void> *) parent.ptr())->value == (void *) src;

Wenzel Jakob's avatar
Wenzel Jakob committed
131
132
        auto& internals = get_internals();
        auto it_instance = internals.registered_instances.find(src);
Wenzel Jakob's avatar
Wenzel Jakob committed
133
134
135
        if (it_instance != internals.registered_instances.end() && !dont_cache)
            return handle((PyObject *) it_instance->second).inc_ref();

136
        auto it = internals.registered_types_cpp.find(std::type_index(*type_info));
137
        if (it == internals.registered_types_cpp.end()) {
138
139
140
            std::string tname = type_info->name();
            detail::clean_type_id(tname);
            std::string msg = "Unregistered type : " + tname;
Wenzel Jakob's avatar
Wenzel Jakob committed
141
            PyErr_SetString(PyExc_TypeError, msg.c_str());
Wenzel Jakob's avatar
Wenzel Jakob committed
142
            return handle();
Wenzel Jakob's avatar
Wenzel Jakob committed
143
        }
Wenzel Jakob's avatar
Wenzel Jakob committed
144

145
        auto tinfo = (const detail::type_info *) it->second;
Wenzel Jakob's avatar
Wenzel Jakob committed
146
147
148
149
150
151
152
153
        object inst(PyType_GenericAlloc(tinfo->type, 0), false);

        auto wrapper = (instance<void> *) inst.ptr();

        wrapper->value = src;
        wrapper->owned = true;
        wrapper->parent = nullptr;

Wenzel Jakob's avatar
Wenzel Jakob committed
154
155
        if (policy == return_value_policy::automatic)
            policy = return_value_policy::take_ownership;
Wenzel Jakob's avatar
Wenzel Jakob committed
156

Wenzel Jakob's avatar
Wenzel Jakob committed
157
        if (policy == return_value_policy::copy) {
Wenzel Jakob's avatar
Wenzel Jakob committed
158
159
            wrapper->value = copy_constructor(wrapper->value);
            if (wrapper->value == nullptr)
160
                throw cast_error("return_value_policy = copy, but the object is non-copyable!");
Wenzel Jakob's avatar
Wenzel Jakob committed
161
        } else if (policy == return_value_policy::reference) {
Wenzel Jakob's avatar
Wenzel Jakob committed
162
            wrapper->owned = false;
Wenzel Jakob's avatar
Wenzel Jakob committed
163
        } else if (policy == return_value_policy::reference_internal) {
Wenzel Jakob's avatar
Wenzel Jakob committed
164
165
            wrapper->owned = false;
            wrapper->parent = parent.inc_ref().ptr();
Wenzel Jakob's avatar
Wenzel Jakob committed
166
        }
Wenzel Jakob's avatar
Wenzel Jakob committed
167
168

        tinfo->init_holder(inst.ptr(), existing_holder);
169
        if (!dont_cache)
Wenzel Jakob's avatar
Wenzel Jakob committed
170
171
172
            internals.registered_instances[wrapper->value] = inst.ptr();

        return inst.release();
Wenzel Jakob's avatar
Wenzel Jakob committed
173
174
175
176
    }

protected:
    const type_info *typeinfo = nullptr;
177
    void *value = nullptr;
Wenzel Jakob's avatar
Wenzel Jakob committed
178
179
180
    object temp;
};

181
/// Generic type caster for objects stored on the heap
182
template <typename type, typename Enable = void> class type_caster : public type_caster_generic {
183
public:
184
    static PYBIND11_DESCR name() { return type_descr(_<type>()); }
185

Wenzel Jakob's avatar
Wenzel Jakob committed
186
    type_caster() : type_caster_generic(typeid(type)) { }
187

Wenzel Jakob's avatar
Wenzel Jakob committed
188
    static handle cast(const type &src, return_value_policy policy, handle parent) {
189
190
        if (policy == return_value_policy::automatic)
            policy = return_value_policy::copy;
191
        return type_caster_generic::cast(&src, policy, parent, &typeid(type), &copy_constructor);
192
193
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
194
    static handle cast(const type *src, return_value_policy policy, handle parent) {
195
        return type_caster_generic::cast(src, policy, parent, &typeid(type), &copy_constructor);
196
197
198
    }

    operator type*() { return (type *) value; }
Wenzel Jakob's avatar
Wenzel Jakob committed
199
    operator type&() { return *((type *) value); }
200
protected:
201
    template <typename T = type, typename std::enable_if<detail::is_copy_constructible<T>::value, int>::type = 0>
202
    static void *copy_constructor(const void *arg) {
203
        return new type(*((const type *) arg));
204
    }
205
    template <typename T = type, typename std::enable_if<!detail::is_copy_constructible<T>::value, int>::type = 0>
206
207
208
    static void *copy_constructor(const void *) { return nullptr; }
};

209
#define PYBIND11_TYPE_CASTER(type, py_name) \
Wenzel Jakob's avatar
Wenzel Jakob committed
210
211
212
    protected: \
        type value; \
    public: \
213
        static PYBIND11_DESCR name() { return type_descr(py_name); } \
Wenzel Jakob's avatar
Wenzel Jakob committed
214
        static handle cast(const type *src, return_value_policy policy, handle parent) { \
Wenzel Jakob's avatar
Wenzel Jakob committed
215
216
217
            return cast(*src, policy, parent); \
        } \
        operator type*() { return &value; } \
Wenzel Jakob's avatar
Wenzel Jakob committed
218
        operator type&() { return value; }
Wenzel Jakob's avatar
Wenzel Jakob committed
219

220
221
222
223
224
225
226
#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
227
228
229
230
231
232
233
234
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
235

Wenzel Jakob's avatar
Wenzel Jakob committed
236
    bool load(handle src, bool) {
Wenzel Jakob's avatar
Wenzel Jakob committed
237
        py_type py_value;
Wenzel Jakob's avatar
Wenzel Jakob committed
238

Wenzel Jakob's avatar
Wenzel Jakob committed
239
        if (std::is_floating_point<T>::value) {
Wenzel Jakob's avatar
Wenzel Jakob committed
240
            py_value = (py_type) PyFloat_AsDouble(src.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
241
242
        } else if (sizeof(T) <= sizeof(long)) {
            if (std::is_signed<T>::value)
Wenzel Jakob's avatar
Wenzel Jakob committed
243
                py_value = (py_type) PyLong_AsLong(src.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
244
            else
Wenzel Jakob's avatar
Wenzel Jakob committed
245
                py_value = (py_type) PyLong_AsUnsignedLong(src.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
246
247
        } else {
            if (std::is_signed<T>::value)
Wenzel Jakob's avatar
Wenzel Jakob committed
248
                py_value = (py_type) PYBIND11_LONG_AS_LONGLONG(src.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
249
            else
Wenzel Jakob's avatar
Wenzel Jakob committed
250
                py_value = (py_type) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(src.ptr());
Wenzel Jakob's avatar
Wenzel Jakob committed
251
252
253
254
255
256
257
258
259
        }

        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
260

Wenzel Jakob's avatar
Wenzel Jakob committed
261
262
263
264
        value = (T) py_value;
        return true;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
265
    static handle cast(T src, return_value_policy /* policy */, handle /* parent */) {
Wenzel Jakob's avatar
Wenzel Jakob committed
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
        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);
        }
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
281
    static handle cast(const T *src, return_value_policy policy, handle parent) {
Wenzel Jakob's avatar
Wenzel Jakob committed
282
283
284
        return cast(*src, policy, parent);
    }

285
286
    template <typename T2 = T, typename std::enable_if<std::is_integral<T2>::value, int>::type = 0>
    static PYBIND11_DESCR name() { return type_descr(_("int")); }
Wenzel Jakob's avatar
Wenzel Jakob committed
287

288
289
    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
290
291
292
293
294
295
296

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

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

298
template <> class type_caster<void_type> {
Wenzel Jakob's avatar
Wenzel Jakob committed
299
public:
Wenzel Jakob's avatar
Wenzel Jakob committed
300
301
302
    bool load(handle, bool) { return false; }
    static handle cast(void_type, return_value_policy /* policy */, handle /* parent */) {
        return handle(Py_None).inc_ref();
Wenzel Jakob's avatar
Wenzel Jakob committed
303
    }
304
    PYBIND11_TYPE_CASTER(void_type, _("NoneType"));
Wenzel Jakob's avatar
Wenzel Jakob committed
305
306
};

Wenzel Jakob's avatar
Wenzel Jakob committed
307
308
template <> class type_caster<void> : public type_caster<void_type> { };
template <> class type_caster<std::nullptr_t> : public type_caster<void_type> { };
309

Wenzel Jakob's avatar
Wenzel Jakob committed
310
311
template <> class type_caster<bool> {
public:
Wenzel Jakob's avatar
Wenzel Jakob committed
312
313
314
    bool load(handle src, bool) {
        if (src.ptr() == Py_True) { value = true; return true; }
        else if (src.ptr() == Py_False) { value = false; return true; }
Wenzel Jakob's avatar
Wenzel Jakob committed
315
316
        else return false;
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
317
318
    static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) {
        return handle(src ? Py_True : Py_False).inc_ref();
Wenzel Jakob's avatar
Wenzel Jakob committed
319
    }
320
    PYBIND11_TYPE_CASTER(bool, _("bool"));
Wenzel Jakob's avatar
Wenzel Jakob committed
321
322
323
324
};

template <> class type_caster<std::string> {
public:
Wenzel Jakob's avatar
Wenzel Jakob committed
325
    bool load(handle src, bool) {
326
        object temp;
Wenzel Jakob's avatar
Wenzel Jakob committed
327
328
329
        handle load_src = src;
        if (PyUnicode_Check(load_src.ptr())) {
            temp = object(PyUnicode_AsUTF8String(load_src.ptr()), false);
330
            if (!temp) { PyErr_Clear(); return false; }  // UnicodeEncodeError
Wenzel Jakob's avatar
Wenzel Jakob committed
331
            load_src = temp;
332
333
334
        }
        char *buffer;
        ssize_t length;
Wenzel Jakob's avatar
Wenzel Jakob committed
335
        int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(load_src.ptr(), &buffer, &length);
336
337
        if (err == -1) { PyErr_Clear(); return false; }  // TypeError
        value = std::string(buffer, length);
Wenzel Jakob's avatar
Wenzel Jakob committed
338
339
        return true;
    }
340

Wenzel Jakob's avatar
Wenzel Jakob committed
341
    static handle cast(const std::string &src, return_value_policy /* policy */, handle /* parent */) {
342
        return PyUnicode_FromStringAndSize(src.c_str(), src.length());
Wenzel Jakob's avatar
Wenzel Jakob committed
343
    }
344
345

    PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
Wenzel Jakob's avatar
Wenzel Jakob committed
346
347
348
349
};

template <> class type_caster<char> {
public:
Wenzel Jakob's avatar
Wenzel Jakob committed
350
    bool load(handle src, bool) {
351
        object temp;
Wenzel Jakob's avatar
Wenzel Jakob committed
352
353
354
        handle load_src = src;
        if (PyUnicode_Check(load_src.ptr())) {
            temp = object(PyUnicode_AsUTF8String(load_src.ptr()), false);
355
            if (!temp) { PyErr_Clear(); return false; }  // UnicodeEncodeError
Wenzel Jakob's avatar
Wenzel Jakob committed
356
            load_src = temp;
357
        }
Wenzel Jakob's avatar
Wenzel Jakob committed
358
        const char *ptr = PYBIND11_BYTES_AS_STRING(load_src.ptr());
359
360
        if (!ptr) { PyErr_Clear(); return false; }  // TypeError
        value = std::string(ptr);
Wenzel Jakob's avatar
Wenzel Jakob committed
361
362
363
        return true;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
364
    static handle cast(const char *src, return_value_policy /* policy */, handle /* parent */) {
Wenzel Jakob's avatar
Wenzel Jakob committed
365
366
367
        return PyUnicode_FromString(src);
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
368
    static handle cast(char src, return_value_policy /* policy */, handle /* parent */) {
Wenzel Jakob's avatar
Wenzel Jakob committed
369
370
371
372
        char str[2] = { src, '\0' };
        return PyUnicode_DecodeLatin1(str, 1, nullptr);
    }

373
374
    operator char*() { return (char *) value.c_str(); }
    operator char() { if (value.length() > 0) return value[0]; else return '\0'; }
375
376

    static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
Wenzel Jakob's avatar
Wenzel Jakob committed
377
protected:
378
    std::string value;
Wenzel Jakob's avatar
Wenzel Jakob committed
379
380
381
382
383
};

template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
    typedef std::pair<T1, T2> type;
public:
Wenzel Jakob's avatar
Wenzel Jakob committed
384
385
    bool load(handle src, bool convert) {
        if (!PyTuple_Check(src.ptr()) || PyTuple_Size(src.ptr()) != 2)
Wenzel Jakob's avatar
Wenzel Jakob committed
386
            return false;
Wenzel Jakob's avatar
Wenzel Jakob committed
387
388
        return  first.load(PyTuple_GET_ITEM(src.ptr(), 0), convert) &&
               second.load(PyTuple_GET_ITEM(src.ptr(), 1), convert);
Wenzel Jakob's avatar
Wenzel Jakob committed
389
390
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
391
392
393
    static handle cast(const type &src, return_value_policy policy, handle parent) {
        object o1 = object(type_caster<typename intrinsic_type<T1>::type>::cast(src.first, policy, parent), false);
        object o2 = object(type_caster<typename intrinsic_type<T2>::type>::cast(src.second, policy, parent), false);
394
        if (!o1 || !o2)
Wenzel Jakob's avatar
Wenzel Jakob committed
395
396
397
398
399
            return handle();
        tuple result(2);
        PyTuple_SET_ITEM(result.ptr(), 0, o1.release().ptr());
        PyTuple_SET_ITEM(result.ptr(), 1, o2.release().ptr());
        return result.release();
Wenzel Jakob's avatar
Wenzel Jakob committed
400
401
    }

402
403
    static PYBIND11_DESCR name() {
        return type_descr(
404
405
            _("(") + type_caster<typename intrinsic_type<T1>::type>::name() +
            _(", ") + type_caster<typename intrinsic_type<T2>::type>::name() + _(")"));
Wenzel Jakob's avatar
Wenzel Jakob committed
406
407
408
409
410
411
    }

    operator type() {
        return type(first, second);
    }
protected:
412
413
    type_caster<typename intrinsic_type<T1>::type> first;
    type_caster<typename intrinsic_type<T2>::type> second;
Wenzel Jakob's avatar
Wenzel Jakob committed
414
415
};

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

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

Wenzel Jakob's avatar
Wenzel Jakob committed
425
    static handle cast(const type &src, return_value_policy policy, handle parent) {
Wenzel Jakob's avatar
Wenzel Jakob committed
426
        return cast(src, policy, parent, typename make_index_sequence<size>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
427
428
    }

429
430
431
    static PYBIND11_DESCR name() {
        return type_descr(
               _("(") +
432
               detail::concat(type_caster<typename intrinsic_type<Tuple>::type>::name()...) +
433
               _(")"));
Wenzel Jakob's avatar
Wenzel Jakob committed
434
435
    }

436
437
    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
438
439
    }

440
    template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, void_type>::type call(Func &&f) {
441
        call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
442
        return void_type();
Wenzel Jakob's avatar
Wenzel Jakob committed
443
444
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
445
    operator type() {
Wenzel Jakob's avatar
Wenzel Jakob committed
446
        return cast(typename make_index_sequence<sizeof...(Tuple)>::type());
Wenzel Jakob's avatar
Wenzel Jakob committed
447
    }
Wenzel Jakob's avatar
Wenzel Jakob committed
448

Wenzel Jakob's avatar
Wenzel Jakob committed
449
protected:
450
    template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
Wenzel Jakob's avatar
Wenzel Jakob committed
451
452
453
454
        return f((Tuple) std::get<Index>(value)...);
    }

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

Wenzel Jakob's avatar
Wenzel Jakob committed
458
459
    template <size_t ... Indices> bool load(handle src, bool convert, index_sequence<Indices...>) {
        if (!PyTuple_Check(src.ptr()) || PyTuple_Size(src.ptr()) != size)
Wenzel Jakob's avatar
Wenzel Jakob committed
460
            return false;
Wenzel Jakob's avatar
Wenzel Jakob committed
461
462
        std::array<bool, size> success {{
            (PyTuple_GET_ITEM(src.ptr(), Indices) != nullptr ? std::get<Indices>(value).load(PyTuple_GET_ITEM(src.ptr(), Indices), convert) : false)...
Wenzel Jakob's avatar
Wenzel Jakob committed
463
        }};
464
        (void) convert; /* avoid a warning when the tuple is empty */
Wenzel Jakob's avatar
Wenzel Jakob committed
465
        for (bool r : success)
Wenzel Jakob's avatar
Wenzel Jakob committed
466
467
468
469
470
471
            if (!r)
                return false;
        return true;
    }

    /* Implementation: Convert a C++ tuple into a Python tuple */
Wenzel Jakob's avatar
Wenzel Jakob committed
472
473
    template <size_t ... Indices> static handle cast(const type &src, return_value_policy policy, handle parent, index_sequence<Indices...>) {
        std::array<object, size> entries {{
474
            object(type_caster<typename intrinsic_type<Tuple>::type>::cast(std::get<Indices>(src), policy, parent), false)...
Wenzel Jakob's avatar
Wenzel Jakob committed
475
        }};
Wenzel Jakob's avatar
Wenzel Jakob committed
476
477
478
479
        for (const auto &entry: entries)
            if (!entry)
                return handle();
        tuple result(size);
480
        int counter = 0;
Wenzel Jakob's avatar
Wenzel Jakob committed
481
482
483
        for (auto & entry: entries)
            PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr());
        return result.release();
Wenzel Jakob's avatar
Wenzel Jakob committed
484
485
486
    }

protected:
487
    std::tuple<type_caster<typename intrinsic_type<Tuple>::type>...> value;
Wenzel Jakob's avatar
Wenzel Jakob committed
488
489
490
491
492
};

/// 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:
493
494
495
496
497
    using type_caster<type>::cast;
    using type_caster<type>::typeinfo;
    using type_caster<type>::value;
    using type_caster<type>::temp;
    using type_caster<type>::copy_constructor;
498

Wenzel Jakob's avatar
Wenzel Jakob committed
499
500
    bool load(handle src, bool convert) {
        if (!src || !typeinfo)
Wenzel Jakob's avatar
Wenzel Jakob committed
501
            return false;
Wenzel Jakob's avatar
Wenzel Jakob committed
502
503
504

        if (PyType_IsSubtype(Py_TYPE(src.ptr()), typeinfo->type)) {
            auto inst = (instance<type, holder_type> *) src.ptr();
505
506
507
508
            value = inst->value;
            holder = inst->holder;
            return true;
        }
Wenzel Jakob's avatar
Wenzel Jakob committed
509

510
511
        if (convert) {
            for (auto &converter : typeinfo->implicit_conversions) {
Wenzel Jakob's avatar
Wenzel Jakob committed
512
513
                temp = object(converter(src.ptr(), typeinfo->type), false);
                if (load(temp, false))
514
515
516
517
                    return true;
            }
        }
        return false;
Wenzel Jakob's avatar
Wenzel Jakob committed
518
    }
519

Wenzel Jakob's avatar
Wenzel Jakob committed
520
521
522
    explicit operator type*() { return this->value; }
    explicit operator type&() { return *(this->value); }
    explicit operator holder_type*() { return &holder; }
523

524
525
526
527
528
529
530
531
    // Workaround for Intel compiler bug
    // see pybind11 issue 94
    #if defined(__ICC) || defined(__INTEL_COMPILER)
    operator holder_type&() { return holder; }
    #else
    explicit operator holder_type&() { return holder; }
    #endif

Wenzel Jakob's avatar
Wenzel Jakob committed
532
    static handle cast(const holder_type &src, return_value_policy policy, handle parent) {
533
534
        return type_caster_generic::cast(
            src.get(), policy, parent, &typeid(type), &copy_constructor, &src);
535
536
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
537
538
539
540
protected:
    holder_type holder;
};

541
542
543
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); } };

544
545
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
546
public:
547
    template <typename T = type, typename std::enable_if<std::is_same<T, handle>::value, int>::type = 0>
Wenzel Jakob's avatar
Wenzel Jakob committed
548
    bool load(handle src, bool /* convert */) { value = src; return value.check(); }
549
550

    template <typename T = type, typename std::enable_if<!std::is_same<T, handle>::value, int>::type = 0>
Wenzel Jakob's avatar
Wenzel Jakob committed
551
    bool load(handle src, bool /* convert */) { value = type(src, true); return value.check(); }
552

Wenzel Jakob's avatar
Wenzel Jakob committed
553
554
    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
        return src.inc_ref();
Wenzel Jakob's avatar
Wenzel Jakob committed
555
    }
556
    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name());
Wenzel Jakob's avatar
Wenzel Jakob committed
557
558
559
560
};

NAMESPACE_END(detail)

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

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

574
575
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
576

577
template <typename... Args> inline object handle::call(Args&&... args_) const {
Wenzel Jakob's avatar
Wenzel Jakob committed
578
    const size_t size = sizeof...(Args);
Wenzel Jakob's avatar
Wenzel Jakob committed
579
    std::array<object, size> args {
580
        { object(detail::type_caster<typename detail::intrinsic_type<Args>::type>::cast(
581
            std::forward<Args>(args_), return_value_policy::reference, nullptr), false)... }
Wenzel Jakob's avatar
Wenzel Jakob committed
582
    };
Wenzel Jakob's avatar
Wenzel Jakob committed
583
584
585
586
587
    for (auto &arg_value : args)
        if (!arg_value)
            throw cast_error("handle::call(): unable to convert input "
                             "arguments to Python objects");
    tuple args_tuple(size);
Wenzel Jakob's avatar
Wenzel Jakob committed
588
    int counter = 0;
Wenzel Jakob's avatar
Wenzel Jakob committed
589
590
591
592
    for (auto &arg_value : args)
        PyTuple_SET_ITEM(args_tuple.ptr(), counter++, arg_value.release().ptr());
    object result(PyObject_CallObject(m_ptr, args_tuple.ptr()), false);
    if (!result)
593
        throw error_already_set();
Wenzel Jakob's avatar
Wenzel Jakob committed
594
    return result;
Wenzel Jakob's avatar
Wenzel Jakob committed
595
596
}

597
NAMESPACE_END(pybind11)