Commit a576e6a8 authored by Wenzel Jakob's avatar Wenzel Jakob
Browse files

keyword argument support, removed last traces of std::function<> usage

parent 71867830
...@@ -24,7 +24,7 @@ string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE) ...@@ -24,7 +24,7 @@ string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
if (UNIX) if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-unsequenced") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-unsequenced")
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG) if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -flto")
endif() endif()
endif() endif()
...@@ -60,6 +60,7 @@ add_library(example SHARED ...@@ -60,6 +60,7 @@ add_library(example SHARED
example/example8.cpp example/example8.cpp
example/example9.cpp example/example9.cpp
example/example10.cpp example/example10.cpp
example/example11.cpp
) )
set_target_properties(example PROPERTIES PREFIX "") set_target_properties(example PROPERTIES PREFIX "")
......
...@@ -56,19 +56,6 @@ In addition to the core functionality, pybind11 provides some extra goodies: ...@@ -56,19 +56,6 @@ In addition to the core functionality, pybind11 provides some extra goodies:
- It is possible to bind C++11 lambda functions with captured variables. The - It is possible to bind C++11 lambda functions with captured variables. The
lambda capture data is stored inside the resulting Python function object. lambda capture data is stored inside the resulting Python function object.
## Limitations
Various things that Boost.Python can do remain unsupported, e.g.:
- Fine grained exception translation: currently, all exceptions derived from
`std::exception` are mapped to a Python `Exception`, but that's it.
- Default arguments in C++ functions are ignored, though their effect can be
emulated by binding multiple overloads using anonymous functions.
- Python keyword arguments are not supported in bindings
- Weak pointers are not supported
## What does the binding code look like? ## What does the binding code look like?
Here is a simple example. The directory `example` contains many more. Here is a simple example. The directory `example` contains many more.
```C++ ```C++
......
...@@ -19,6 +19,7 @@ void init_ex7(py::module &); ...@@ -19,6 +19,7 @@ void init_ex7(py::module &);
void init_ex8(py::module &); void init_ex8(py::module &);
void init_ex9(py::module &); void init_ex9(py::module &);
void init_ex10(py::module &); void init_ex10(py::module &);
void init_ex11(py::module &);
PYTHON_PLUGIN(example) { PYTHON_PLUGIN(example) {
py::module m("example", "pybind example plugin"); py::module m("example", "pybind example plugin");
...@@ -33,6 +34,7 @@ PYTHON_PLUGIN(example) { ...@@ -33,6 +34,7 @@ PYTHON_PLUGIN(example) {
init_ex8(m); init_ex8(m);
init_ex9(m); init_ex9(m);
init_ex10(m); init_ex10(m);
init_ex11(m);
return m.ptr(); return m.ptr();
} }
/* /*
example/example1.cpp -- Example 1: constructors, deconstructors, example/example1.cpp -- constructors, deconstructors, attribute access,
attribute access, __str__, argument and return value conventions __str__, argument and return value conventions
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example10.cpp -- Example 10: auto-vectorize functions for NumPy example/example10.cpp -- auto-vectorize functions over NumPy array
arguments
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
...@@ -20,14 +21,16 @@ std::complex<double> my_func3(std::complex<double> c) { ...@@ -20,14 +21,16 @@ std::complex<double> my_func3(std::complex<double> c) {
} }
void init_ex10(py::module &m) { void init_ex10(py::module &m) {
// Vectorize all arguments (though non-vector arguments are also allowed) // Vectorize all arguments of a function (though non-vector arguments are also allowed)
m.def("vectorized_func", py::vectorize(my_func)); m.def("vectorized_func", py::vectorize(my_func));
// Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization) // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization)
m.def("vectorized_func2", m.def("vectorized_func2",
[](py::array_dtype<int> x, py::array_dtype<float> y, float z) { [](py::array_dtype<int> x, py::array_dtype<float> y, float z) {
return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(x, y); return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(x, y);
} }
); );
// Vectorize all arguments (complex numbers)
// Vectorize a complex-valued function
m.def("vectorized_func3", py::vectorize(my_func3)); m.def("vectorized_func3", py::vectorize(my_func3));
} }
File mode changed from 100644 to 100755
/*
example/example11.cpp -- keyword arguments and default values
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"
void kw_func(int x, int y) { std::cout << "kw_func(x=" << x << ", y=" << y << ")" << std::endl; }
void init_ex11(py::module &m) {
m.def("kw_func", &kw_func, py::arg("x"), py::arg("y"));
m.def("kw_func2", &kw_func, py::arg("x") = 100, py::arg("y") = 200);
}
#!/usr/bin/env python3
import sys, pydoc
sys.path.append('.')
import example
from example import kw_func
from example import kw_func2
print(pydoc.render_doc(kw_func, "Help on %s"))
print(pydoc.render_doc(kw_func2, "Help on %s"))
kw_func(5, 10)
kw_func(5, y = 10)
kw_func(y = 10, x = 5)
kw_func2()
kw_func2(5)
kw_func2(x=5)
kw_func2(y=10)
kw_func2(5, 10)
kw_func2(x=5, y=10)
/* /*
example/example2.cpp2 -- Example 2: singleton design pattern, static example/example2.cpp2 -- singleton design pattern, static functions and
functions and variables, passing and interacting with Python types variables, passing and interacting with Python types
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example3.cpp -- Example 3: operator overloading example/example3.cpp -- operator overloading
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example4.cpp -- Example 4: global constants and functions, enumerations example/example4.cpp -- global constants and functions, enumerations
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example5.cpp -- Example 5: inheritance, callbacks, acquiring example/example5.cpp -- inheritance, callbacks, acquiring and releasing the
and releasing the global interpreter lock global interpreter lock
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example6.cpp -- Example 6: supporting Pythons' sequence example/example6.cpp -- supporting Pythons' sequence protocol, iterators,
protocol, iterators, etc. etc.
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example7.cpp -- Example 7: supporting Pythons' buffer protocol example/example7.cpp -- supporting Pythons' buffer protocol
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
/* /*
example/example8.cpp -- Example 8: binding classes with example/example8.cpp -- binding classes with custom reference counting,
custom reference counting, implicit conversions between types implicit conversions between types
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
File mode changed from 100644 to 100755
/* /*
example/example9.cpp -- Example 9: nested modules example/example9.cpp -- nested modules and internal references
and internal references
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
...@@ -392,14 +392,22 @@ public: ...@@ -392,14 +392,22 @@ public:
return cast(src, policy, parent, typename make_index_sequence<size>::type()); return cast(src, policy, parent, typename make_index_sequence<size>::type());
} }
static std::string name() { static std::string name(const char **keywords = nullptr, const char **values = nullptr) {
std::array<std::string, size> names {{ std::array<std::string, size> names {{
type_caster<typename detail::decay<Tuple>::type>::name()... type_caster<typename detail::decay<Tuple>::type>::name()...
}}; }};
std::string result("("); std::string result("(");
int counter = 0; int counter = 0;
for (auto const &name : names) { for (auto const &name : names) {
if (keywords && keywords[counter]) {
result += keywords[counter];
result += " : ";
}
result += name; result += name;
if (values && values[counter]) {
result += " = ";
result += values[counter];
}
if (++counter < size) if (++counter < size)
result += ", "; result += ", ";
} }
...@@ -407,12 +415,12 @@ public: ...@@ -407,12 +415,12 @@ public:
return result; return result;
} }
template <typename ReturnValue, typename Func> typename std::enable_if<!std::is_void<ReturnValue>::value, ReturnValue>::type call(Func &f) { template <typename ReturnValue, typename Func> typename std::enable_if<!std::is_void<ReturnValue>::value, ReturnValue>::type call(Func &&f) {
return call<ReturnValue, Func>(f, typename make_index_sequence<sizeof...(Tuple)>::type()); return call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
} }
template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, detail::void_type>::type call(Func &f) { template <typename ReturnValue, typename Func> typename std::enable_if<std::is_void<ReturnValue>::value, detail::void_type>::type call(Func &&f) {
call<ReturnValue, Func>(f, typename make_index_sequence<sizeof...(Tuple)>::type()); call<ReturnValue>(std::forward<Func>(f), typename make_index_sequence<sizeof...(Tuple)>::type());
return detail::void_type(); return detail::void_type();
} }
...@@ -421,7 +429,7 @@ public: ...@@ -421,7 +429,7 @@ public:
} }
protected: protected:
template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &f, index_sequence<Index...>) { template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
return f((Tuple) std::get<Index>(value)...); return f((Tuple) std::get<Index>(value)...);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment