summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanek Bevendorff <janek@jbev.net>2021-07-13 21:20:37 +0200
committerGitHub <noreply@github.com>2021-07-13 21:20:37 +0200
commita46ed3f401b0f7520566cacd25261d612784b3a4 (patch)
treea511974e547dcb7126d7b0d6e64ade8c0ecdc4d9
parentfae33cf7d42559384deb7a9949f47b0881b0a29b (diff)
downloadcython-a46ed3f401b0f7520566cacd25261d612784b3a4.tar.gz
Fix "std::string::npos" in 'libcpp.string' and add missing C++ string methods (GH-4276)
Closes https://github.com/cython/cython/issues/4268
-rw-r--r--Cython/Includes/libcpp/string.pxd196
-rw-r--r--tests/run/cpp_stl_string.pyx58
2 files changed, 169 insertions, 85 deletions
diff --git a/Cython/Includes/libcpp/string.pxd b/Cython/Includes/libcpp/string.pxd
index 2eecab217..b5c5c5ee1 100644
--- a/Cython/Includes/libcpp/string.pxd
+++ b/Cython/Includes/libcpp/string.pxd
@@ -2,16 +2,15 @@
# deprecated cimport for backwards compatibility:
from libc.string cimport const_char
+cdef extern from "<string>" namespace "std::string" nogil:
+ const size_t npos
cdef extern from "<string>" namespace "std" nogil:
-
- size_t npos = -1
-
cdef cppclass string:
cppclass iterator:
iterator()
char& operator*()
- iterator(iterator &)
+ iterator(iterator&)
iterator operator++()
iterator operator--()
bint operator==(iterator)
@@ -34,12 +33,12 @@ cdef extern from "<string>" namespace "std" nogil:
pass
string() except +
- string(const char *) except +
- string(const char *, size_t) except +
- string(const string&) except +
- # as a string formed by a repetition of character c, n times.
- string(size_t, char) except +
- # from a pair of iterators
+ string(const string& s) except +
+ string(const string& s, size_t pos) except +
+ string(const string& s, size_t pos, size_t len) except +
+ string(const char* s) except +
+ string(const char* s, size_t n) except +
+ string(size_t n, char c) except +
string(iterator first, iterator last) except +
iterator begin()
@@ -56,111 +55,122 @@ cdef extern from "<string>" namespace "std" nogil:
size_t size()
size_t max_size()
size_t length()
- void resize(size_t)
- void resize(size_t, char c)
+ void resize(size_t) except +
+ void resize(size_t, char) except +
+ void shrink_to_fit() except +
size_t capacity()
- void reserve(size_t)
+ void reserve(size_t) except +
void clear()
bint empty()
- iterator erase(iterator position)
- iterator erase(const_iterator position)
iterator erase(iterator first, iterator last)
+ iterator erase(iterator p)
iterator erase(const_iterator first, const_iterator last)
-
- char& at(size_t) except +
- char& operator[](size_t)
- char& front() # C++11
- char& back() # C++11
- int compare(const string&)
-
- string& append(const string&) except +
- string& append(const string&, size_t, size_t) except +
- string& append(const char *) except +
- string& append(const char *, size_t) except +
- string& append(size_t, char) except +
+ iterator erase(const_iterator p)
+ string& erase(size_t pos, size_t len) except +
+ string& erase(size_t pos) except +
+ string& erase() except +
+
+ char& at(size_t pos) except +
+ char& operator[](size_t pos)
+ char& front()
+ char& back()
+ int compare(const string& s)
+ int compare(size_t pos, size_t len, const string& s) except +
+ int compare(size_t pos, size_t len, const string& s, size_t subpos, size_t sublen) except +
+ int compare(const char* s) except +
+ int compare(size_t pos, size_t len, const char* s) except +
+ int compare(size_t pos, size_t len, const char* s , size_t n) except +
+
+ string& append(const string& s) except +
+ string& append(const string& s, size_t subpos, size_t sublen) except +
+ string& append(const char* s) except +
+ string& append(const char* s, size_t n) except +
+ string& append(size_t n, char c) except +
void push_back(char c) except +
-
- string& assign (const string&)
- string& assign (const string&, size_t, size_t)
- string& assign (const char *, size_t)
- string& assign (const char *)
- string& assign (size_t n, char c)
-
- string& insert(size_t, const string&) except +
- string& insert(size_t, const string&, size_t, size_t) except +
- string& insert(size_t, const char* s, size_t) except +
-
-
- string& insert(size_t, const char* s) except +
- string& insert(size_t, size_t, char c) except +
-
- size_t copy(char *, size_t, size_t) except +
-
- size_t find(const string&, size_t pos)
- size_t find(const string&)
- size_t find(const char*, size_t pos, size_t n)
- size_t find(const char*, size_t pos)
- size_t find(const char*)
+ void pop_back()
+
+ string& assign (const string& s) except +
+ string& assign (const string& s, size_t subpos, size_t sublen) except +
+ string& assign (const char* s, size_t n) except +
+ string& assign (const char* s) except +
+ string& assign (size_t n, char c) except +
+
+ string& insert(size_t pos, const string& s, size_t subpos, size_t sublen) except +
+ string& insert(size_t pos, const string& s) except +
+ string& insert(size_t pos, const char* s, size_t n) except +
+ string& insert(size_t pos, const char* s) except +
+ string& insert(size_t pos, size_t n, char c) except +
+ void insert(iterator p, size_t n, char c) except +
+ iterator insert(iterator p, char c) except +
+
+ size_t copy(char* s, size_t len, size_t pos) except +
+ size_t copy(char* s, size_t len) except +
+
+ size_t find(const string& s, size_t pos)
+ size_t find(const string& s)
+ size_t find(const char* s, size_t pos, size_t n)
+ size_t find(const char* s, size_t pos)
+ size_t find(const char* s)
size_t find(char c, size_t pos)
size_t find(char c)
size_t rfind(const string&, size_t pos)
size_t rfind(const string&)
size_t rfind(const char* s, size_t pos, size_t n)
- size_t rfind(const char*, size_t pos)
- size_t rfind(const char*)
+ size_t rfind(const char* s, size_t pos)
+ size_t rfind(const char* s)
size_t rfind(char c, size_t pos)
size_t rfind(char c)
size_t find_first_of(const string&, size_t pos)
size_t find_first_of(const string&)
size_t find_first_of(const char* s, size_t pos, size_t n)
- size_t find_first_of(const char*, size_t pos)
- size_t find_first_of(const char*)
+ size_t find_first_of(const char* s, size_t pos)
+ size_t find_first_of(const char* s)
size_t find_first_of(char c, size_t pos)
size_t find_first_of(char c)
- size_t find_first_not_of(const string&, size_t pos)
- size_t find_first_not_of(const string&)
- size_t find_first_not_of(const char* s, size_t, size_t)
- size_t find_first_not_of(const char*, size_t pos)
+ size_t find_first_not_of(const string& s, size_t pos)
+ size_t find_first_not_of(const string& s)
+ size_t find_first_not_of(const char* s, size_t pos, size_t n)
+ size_t find_first_not_of(const char* s, size_t pos)
size_t find_first_not_of(const char*)
size_t find_first_not_of(char c, size_t pos)
size_t find_first_not_of(char c)
- size_t find_last_of(const string&, size_t pos)
- size_t find_last_of(const string&)
+ size_t find_last_of(const string& s, size_t pos)
+ size_t find_last_of(const string& s)
size_t find_last_of(const char* s, size_t pos, size_t n)
- size_t find_last_of(const char*, size_t pos)
- size_t find_last_of(const char*)
+ size_t find_last_of(const char* s, size_t pos)
+ size_t find_last_of(const char* s)
size_t find_last_of(char c, size_t pos)
size_t find_last_of(char c)
- size_t find_last_not_of(const string&, size_t pos)
- size_t find_last_not_of(const string&)
+ size_t find_last_not_of(const string& s, size_t pos)
+ size_t find_last_not_of(const string& s)
size_t find_last_not_of(const char* s, size_t pos, size_t n)
- size_t find_last_not_of(const char*, size_t pos)
- size_t find_last_not_of(const char*)
+ size_t find_last_not_of(const char* s, size_t pos)
+ size_t find_last_not_of(const char* s)
size_t find_last_not_of(char c, size_t pos)
size_t find_last_not_of(char c)
- string substr(size_t, size_t) except +
+ string substr(size_t pos, size_t len) except +
+ string substr(size_t pos) except +
string substr()
- string substr(size_t) except +
#string& operator= (const string&)
#string& operator= (const char*)
#string& operator= (char)
- string operator+ (const string& rhs) except +
- string operator+ (const char* rhs) except +
+ string operator+ (const string&) except +
+ string operator+ (const char*) except +
bint operator==(const string&)
bint operator==(const char*)
- bint operator!= (const string& rhs )
- bint operator!= (const char* )
+ bint operator!= (const string&)
+ bint operator!= (const char*)
bint operator< (const string&)
bint operator< (const char*)
@@ -175,12 +185,38 @@ cdef extern from "<string>" namespace "std" nogil:
bint operator>= (const char*)
- string to_string(int val)
- string to_string(long val)
- string to_string (long long val)
- string to_string (unsigned val)
- string to_string (unsigned long val)
- string to_string (unsigned long long val)
- string to_string (float val)
- string to_string (double val)
- string to_string (long double val)
+ string to_string(int val) except +
+ string to_string(long val) except +
+ string to_string(long long val) except +
+ string to_string(unsigned val) except +
+ string to_string(size_t val) except +
+ string to_string(ssize_t val) except +
+ string to_string(unsigned long val) except +
+ string to_string(unsigned long long val) except +
+ string to_string(float val) except +
+ string to_string(double val) except +
+ string to_string(long double val) except +
+
+ int stoi(const string& s, size_t* idx, int base) except +
+ int stoi(const string& s, size_t* idx) except +
+ int stoi(const string& s) except +
+ long stol(const string& s, size_t* idx, int base) except +
+ long stol(const string& s, size_t* idx) except +
+ long stol(const string& s) except +
+ long long stoll(const string& s, size_t* idx, int base) except +
+ long long stoll(const string& s, size_t* idx) except +
+ long long stoll(const string& s) except +
+
+ unsigned long stoul(const string& s, size_t* idx, int base) except +
+ unsigned long stoul(const string& s, size_t* idx) except +
+ unsigned long stoul(const string& s) except +
+ unsigned long long stoull(const string& s, size_t* idx, int base) except +
+ unsigned long long stoull(const string& s, size_t* idx) except +
+ unsigned long long stoull(const string& s) except +
+
+ float stof(const string& s, size_t* idx) except +
+ float stof(const string& s) except +
+ double stod(const string& s, size_t* idx) except +
+ double stod(const string& s) except +
+ long double stold(const string& s, size_t* idx) except +
+ long double stold(const string& s) except +
diff --git a/tests/run/cpp_stl_string.pyx b/tests/run/cpp_stl_string.pyx
index 1b0905df8..fb69a9dee 100644
--- a/tests/run/cpp_stl_string.pyx
+++ b/tests/run/cpp_stl_string.pyx
@@ -3,7 +3,7 @@
cimport cython
-from libcpp.string cimport string, to_string
+from libcpp.string cimport string, npos, to_string, stoi, stof
b_asdf = b'asdf'
b_asdg = b'asdg'
@@ -102,6 +102,15 @@ def test_push_back(char *a):
s.push_back(<char>ord('s'))
return s.c_str()
+def test_pop_back(char *a):
+ """
+ >>> test_pop_back(b'abc') == b'ab' or test_pop_back(b'abc')
+ True
+ """
+ cdef string s = string(a)
+ s.pop_back()
+ return s
+
def test_insert(char *a, char *b, int i):
"""
>>> test_insert('AAAA'.encode('ASCII'), 'BBBB'.encode('ASCII'), 2) == 'AABBBBAA'.encode('ASCII')
@@ -133,6 +142,17 @@ def test_find(char *a, char *b):
cdef size_t i = s.find(t)
return i
+def test_npos(char *a, char *b):
+ """
+ >>> test_npos(b'abc', b'x')
+ True
+ >>> test_npos(b'abc', b'a')
+ False
+ """
+ cdef string s = string(a)
+ cdef string st = string(b)
+ return s.find(st) == npos
+
def test_clear():
"""
>>> test_clear() == ''.encode('ASCII')
@@ -142,6 +162,18 @@ def test_clear():
s.clear()
return s.c_str()
+def test_erase(char *a, size_t pos=0, size_t count=npos):
+ """
+ >>> test_erase(b'abc') == b'' or test_erase(b'abc')
+ True
+ >>> test_erase(b'abc', 1) == b'a' or test_erase(b'abc', 1)
+ True
+ >>> test_erase(b'abc', 1, 1) == b'ac' or test_erase(b'abc', 1, 1)
+ True
+ """
+ cdef string s = string(a)
+ return s.erase(pos, count)
+
def test_assign(char *a):
"""
>>> test_assign(b_asdf) == 'ggg'.encode('ASCII')
@@ -345,18 +377,34 @@ def test_iteration(string s):
"""
return [c for c in s]
-
def test_to_string(x):
"""
>>> print(test_to_string(5))
- si=5 sl=5
+ si=5 sl=5 ss=5 sss=5
>>> print(test_to_string(-5))
- si=-5 sl=-5
+ si=-5 sl=-5 ss=5 sss=-5
"""
si = to_string(<int>x).decode('ascii')
sl = to_string(<long>x).decode('ascii')
- return f"si={si} sl={sl}"
+ ss = to_string(<size_t>abs(x)).decode('ascii')
+ sss = to_string(<ssize_t>x).decode('ascii')
+ return f"si={si} sl={sl} ss={ss} sss={sss}"
+def test_stoi(char *a):
+ """
+ >>> test_stoi(b'5')
+ 5
+ """
+ cdef string s = string(a)
+ return stoi(s)
+
+def test_stof(char *a):
+ """
+ >>> test_stof(b'5.5')
+ 5.5
+ """
+ cdef string s = string(a)
+ return stof(s)
_WARNINGS = """
21:31: Cannot pass Python object as C++ data structure reference (string &), will pass by copy.