example2.cpp 4.44 KB
Newer Older
Wenzel Jakob's avatar
Wenzel Jakob committed
1
/*
2
3
    example/example2.cpp2 -- singleton design pattern, static functions and
    variables, passing and interacting with Python types
Wenzel Jakob's avatar
Wenzel Jakob committed
4
5
6
7
8
9
10
11

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

#include "example.h"
12
#include <pybind/stl.h>
Wenzel Jakob's avatar
Wenzel Jakob committed
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
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
109
110
111
112
113
114
115
116
117
118

class Example2 {
public:
    static Example2 *new_instance() {
        return new Example2();
    }
    ~Example2() {
        std::cout << "Destructing Example2" << std::endl;
    }

    /* Create and return a Python dictionary */
    py::dict get_dict() {
        py::dict dict;
        dict[py::str("key")] = py::str("value");
        return dict;
    }

    /* Create and return a C++ dictionary */
    std::map<std::string, std::string> get_dict_2() {
        std::map<std::string, std::string> result;
        result["key"] = "value";
        return result;
    }

    /* Create, manipulate, and return a Python list */
    py::list get_list() {
        py::list list;
        list.append(py::str("value"));
        cout << "Entry at positon 0: " << py::object(list[0]) << endl;
        list[0] = py::str("overwritten");
        return list;
    }

    /* C++ STL data types are automatically casted */
    std::vector<std::string> get_list_2() {
        std::vector<std::string> list;
        list.push_back("value");
        return list;
    }

    /* Easily iterate over a dictionary using a C++11 range-based for loop */
    void print_dict(py::dict dict) {
        for (auto item : dict)
            std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
    }

    /* STL data types are automatically casted from Python */
    void print_dict_2(const std::map<std::string, std::string> &dict) {
        for (auto item : dict)
            std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
    }

    /* Easily iterate over a list using a C++11 range-based for loop */
    void print_list(py::list list) {
        int index = 0;
        for (auto item : list)
            std::cout << "list item " << index++ << ": " << item << std::endl;
    }

    /* STL data types are automatically casted from Python */
    void print_list_2(std::vector<std::string> &list) {
        int index = 0;
        for (auto item : list)
            std::cout << "list item " << index++ << ": " << item << std::endl;
    }

    /* pybind automatically translates between C++11 and Python tuples */
    std::pair<std::string, bool> pair_passthrough(std::pair<bool, std::string> input) {
        return std::make_pair(input.second, input.first);
    }

    /* pybind automatically translates between C++11 and Python tuples */
    std::tuple<int, std::string, bool> tuple_passthrough(std::tuple<bool, std::string, int> input) {
        return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input));
    }

    void throw_exception() {
        throw std::runtime_error("This exception was intentionally thrown.");
    }

    static int value;
    static const int value2;
};

int Example2::value = 0;
const int Example2::value2 = 5;

void init_ex2(py::module &m) {
    /* No constructor is explicitly defined below. An exception is raised when
       trying to construct it directly from Python */
    py::class_<Example2>(m, "Example2")
        .def("get_dict", &Example2::get_dict, "Return a Python dictionary")
        .def("get_dict_2", &Example2::get_dict_2, "Return a C++ dictionary")
        .def("get_list", &Example2::get_list, "Return a Python list")
        .def("get_list_2", &Example2::get_list_2, "Return a C++ list")
        .def("print_dict", &Example2::print_dict, "Print entries of a Python dictionary")
        .def("print_dict_2", &Example2::print_dict_2, "Print entries of a C++ dictionary")
        .def("print_list", &Example2::print_list, "Print entries of a Python list")
        .def("print_list_2", &Example2::print_list_2, "Print entries of a C++ list")
        .def("pair_passthrough", &Example2::pair_passthrough, "Return a pair in reversed order")
        .def("tuple_passthrough", &Example2::tuple_passthrough, "Return a triple in reversed order")
        .def("throw_exception", &Example2::throw_exception, "Throw an exception")
        .def_static("new_instance", &Example2::new_instance, "Return an instance")
        .def_readwrite_static("value", &Example2::value, "Static value member")
        .def_readonly_static("value2", &Example2::value2, "Static value member (readonly)");
}