-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
std::move missing from libcpp #2169
Comments
I attempted declaring This is the definition of template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept; This is test.pyx file I will use for demonstration: # distutils: language = c++
cdef extern from *:
"""
#include <iostream>
#define PRINT() std::cout << __PRETTY_FUNCTION__ << std::endl
struct Test {
Test() { PRINT(); }
~Test() { PRINT(); }
Test(const Test&) { PRINT(); }
Test(Test&&) { PRINT(); }
Test& operator=(const Test&) { PRINT(); return *this; }
Test& operator=(Test&&) { PRINT(); return *this; }
};
void f(const Test&) { PRINT(); }
void f(Test&&) { PRINT(); }
"""
cdef cppclass Test:
pass
cdef void f(Test)
from move cimport move
cdef Test t1, t2
print("# t1 = t2")
t1 = t2
print("# t1 = move(t2)")
t1 = move(t2)
print("# f(t1)")
f(t1)
print("# f(move(t1))")
f(move(t1))
print("# f(move(move(t1)))")
f(move(move(t1)))
print("# f(move(move(move(t1))))")
f(move(move(move(t1))))
First attempt at move.pxd: # distutils: language = c++
cdef extern from "<utility>" namespace "std" nogil:
cdef T&& move[T](T&&) Compiling test.pyx returns bunch of errors, but the first one was:
So, the issue is that cython explicitly provides template argument Another way would be having a wrapper which accepts above template parameter and calls # distutils: language = c++
cdef extern from * namespace "polyfill":
"""
#include <type_traits>
#include <utility>
namespace polyfill {
template <typename T>
inline typename std::remove_reference<T>::type&& move(T& t) {
return std::move(t);
}
template <typename T>
inline typename std::remove_reference<T>::type&& move(T&& t) {
return std::move(t);
}
} // namespace pf
"""
cdef T&& move[T](T&)
cdef T&& move[T](T&&) This causes error for three level nested move:
So the return value being declared as xvalue is the culprit. From what I understood it doesn't matter if a function's parameter/return type is xvalue, prvalue or lvalue from cython's point of view, so we can simplify above code as: # distutils: language = c++
cdef extern from * namespace "polyfill":
"""
#include <type_traits>
#include <utility>
namespace polyfill {
template <typename T>
inline typename std::remove_reference<T>::type&& move(T& t) {
return std::move(t);
}
template <typename T>
inline typename std::remove_reference<T>::type&& move(T&& t) {
return std::move(t);
}
} // namespace pf
"""
cdef T move[T](T) It compiles and works correctly:
I can submit a PR for embedding above wrapper snippet into |
I packaged it as cymove for now. |
Thanks for looking into this. We'd welcome a PR to put the solution with the template wrapper into Cython itself. |
I submitted a PR over the weekend. It's ready to be merged if there are no changes needed. I'd appreciate if you could review it. |
Since it seems tricky to find the right declaration spelling for
std::move
(if at all possible?), it would be nice to have it predeclared inlibcpp
.The text was updated successfully, but these errors were encountered: