functional.h 1.42 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
    pybind/functional.h: std::function<> 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 <functional>

NAMESPACE_BEGIN(pybind)
NAMESPACE_BEGIN(detail)

template <typename Return, typename... Args> struct type_caster<std::function<Return(Args...)>> {
    typedef std::function<Return(Args...)> type;
public:

    bool load(PyObject *src_, bool) {
        if (!PyFunction_Check(src_))
            return false;
        object src(src_, true);
        value = [src](Args... args) -> Return {
            object retval(pybind::handle(src).call<Args...>(std::move(args)...));
            /* Visual studio 2015 parser issue: need parentheses around this expression */
            return (retval.template cast<Return>());
        };
        return true;
    }

    template <typename Func>
    static PyObject *cast(Func &&f_, return_value_policy policy, PyObject *) {
        cpp_function f(std::forward<Func>(f_), policy);
        f.inc_ref();
        return f.ptr();
    }

41
42
43
44
45

    PYBIND_TYPE_CASTER(type, detail::descr("function<") +
            type_caster<std::tuple<Args...>>::descr() + detail::descr(" -> ") +
            type_caster<typename decay<Return>::type>::descr() +
            detail::descr(">"));
46
47
48
49
};

NAMESPACE_END(detail)
NAMESPACE_END(pybind)