example2.cpp 5.58 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 <pybind11/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

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;
    }

30
31
32
    /* Create and return a Python set */
    py::set get_set() {
        py::set set;
33
34
        set.add(py::str("key1"));
        set.add(py::str("key2"));
35
36
37
        return set;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
38
39
40
41
42
43
44
    /* 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;
    }

45
46
47
48
49
50
51
52
    /* Create and return a C++ set */
    std::set<std::string> get_set_2() {
        std::set<std::string> result;
        result.insert("key1");
        result.insert("key2");
        return result;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    /* 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;
    }

75
    /* Easily iterate over a set using a C++11 range-based for loop */
76
77
78
79
80
    void print_set(py::set set) {
        for (auto item : set)
            std::cout << "key: " << item << std::endl;
    }

Wenzel Jakob's avatar
Wenzel Jakob committed
81
82
83
84
85
86
87
    /* 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;
    }

88
89
90
91
92
93
94
95
96
97
98
99
100
    /* STL data types (such as maps) 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;
    }

    /* STL data types (such as sets) are automatically casted from Python */
    void print_set_2(const std::set<std::string> &set) {
        for (auto item : set)
            std::cout << "key: " << item << std::endl;
    }

    /* STL data types (such as vectors) are automatically casted from Python */
Wenzel Jakob's avatar
Wenzel Jakob committed
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    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 */
Wenzel Jakob's avatar
Wenzel Jakob committed
131
    py::class_<Example2>(m, "Example2", "Example 2 documentation")
Wenzel Jakob's avatar
Wenzel Jakob committed
132
133
134
135
        .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")
136
137
        .def("get_set", &Example2::get_set, "Return a Python set")
        .def("get_set2", &Example2::get_set, "Return a C++ set")
Wenzel Jakob's avatar
Wenzel Jakob committed
138
139
        .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")
140
141
        .def("print_set", &Example2::print_set, "Print entries of a Python set")
        .def("print_set_2", &Example2::print_set_2, "Print entries of a C++ set")
Wenzel Jakob's avatar
Wenzel Jakob committed
142
143
144
145
146
147
148
149
150
        .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)");
}