Commit 2ddd8aaa authored by Xavier Thompson's avatar Xavier Thompson

Add GIL-free string implementation

parent 057c47b1
cdef extern from "<string_view>" namespace "std::string_view" nogil:
const size_t npos
cdef extern from "<string_view>" namespace "std" nogil:
cdef cppclass string_view:
cppclass iterator:
iterator()
char& operator*()
iterator(iterator&)
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
cppclass reverse_iterator:
char& operator*()
iterator operator++()
iterator operator--()
iterator operator+(size_t)
iterator operator-(size_t)
bint operator==(reverse_iterator)
bint operator!=(reverse_iterator)
bint operator<(reverse_iterator)
bint operator>(reverse_iterator)
bint operator<=(reverse_iterator)
bint operator>=(reverse_iterator)
cppclass const_iterator(iterator):
pass
cppclass const_reverse_iterator(reverse_iterator):
pass
string_view() except +
string_view(const string_view& s) except +
string_view(const char* s) except +
string_view(const char* s, size_t n) except +
string_view(iterator first, iterator last) except +
string_view& operator= (const string_view&)
iterator begin()
const_iterator const_begin "begin"()
iterator end()
const_iterator const_end "end"()
reverse_iterator rbegin()
const_reverse_iterator const_rbegin "rbegin"()
reverse_iterator rend()
const_reverse_iterator const_rend "rend"()
char* data()
size_t size()
size_t max_size()
size_t length()
void swap(string_view& other)
bint empty()
char& at(size_t pos) except +
char& operator[](size_t pos)
char& front()
char& back()
int compare(const string_view& s)
int compare(size_t pos, size_t len, const string_view& s) except +
int compare(size_t pos, size_t len, const string_view& 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 +
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_view& s, size_t pos)
size_t find(const string_view& 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_view&, size_t pos)
size_t rfind(const string_view&)
size_t rfind(const char* s, size_t pos, size_t n)
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_view&, size_t pos)
size_t find_first_of(const string_view&)
size_t find_first_of(const char* s, size_t pos, size_t n)
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_view& s, size_t pos)
size_t find_first_not_of(const string_view& 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_view& s, size_t pos)
size_t find_last_of(const string_view& s)
size_t find_last_of(const char* s, size_t pos, size_t n)
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_view& s, size_t pos)
size_t find_last_not_of(const string_view& s)
size_t find_last_not_of(const char* s, size_t pos, size_t n)
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_view substr(size_t pos, size_t len) except +
string_view substr(size_t pos) except +
string_view substr()
bint operator==(const string_view&)
bint operator==(const char*)
bint operator!= (const string_view&)
bint operator!= (const char*)
bint operator< (const string_view&)
bint operator< (const char*)
bint operator> (const string_view&)
bint operator> (const char*)
bint operator<= (const string_view&)
bint operator<= (const char*)
bint operator>= (const string_view&)
bint operator>= (const char*)
from stdlib._string cimport string_view
from libc.string cimport strlen, strncpy
from libc.stdlib cimport malloc, free
cdef cypclass Str:
string_view _s
__init__(self, const char *s):
cdef size_t l = strlen(s)
cdef char *_s = <char *> malloc(l + 1)
strncpy(_s, s, l + 1)
self._s = string_view(_s, l)
__dealloc__(self):
cdef char *s = <char *> self._s.data()
self._s = string_view()
free(s)
size_t __len__(self):
return self._s.size()
bint __eq__(self, Str other):
return self._s == other._s
char __getitem__(self, int index) except 0:
cdef int end = self._s.size()
cdef int idx = index
if index < 0:
index = -index
idx = end - index
if index >= end:
with gil:
raise ValueError('index out of range')
return self._s.data()[idx]
int find(self, Str s, size_t start=0, size_t stop=0):
if start < stop and stop <= self._s.size():
sw = string_view(self._s.data(), stop)
return sw.find(s._s, start)
return self._s.find(s._s, start)
Str slice(self, int start=0, int stop=0) except NULL:
cdef int end = self._s.size()
cdef int tmp = stop
if stop <= 0:
stop = -stop
tmp = end - stop
if stop > end:
with gil:
raise ValueError('slice bounds out of range')
stop = tmp
if start < 0:
start = -start
if start > end:
with gil:
raise ValueError('slice bounds out of range')
start = end - start
if start >= stop:
with gil:
raise ValueError('slice bounds out of order')
cdef size_t size = stop - start
cdef char *s = <char *> malloc(size + 1)
strncpy(s, self._s.data() + start, size)
s[size] = 0
result = Str()
result._s = string_view(s, size)
return result
Str __add__(self, Str other):
cdef size_t l1 = self._s.size()
cdef size_t l2 = other._s.size()
cdef Str cat = new Str()
cdef char *s = <char *> malloc(l1 + l2 + 1)
strncpy(s, self._s.data(), l1)
strncpy(s + l1, other._s.data(), l2 + 1)
cat._s = string_view(s, l1 + l2)
return cat
const char * to_c_str(self):
return self._s.data()
@staticmethod
Str steal_c_str(const char *s, size_t size):
result = Str()
result._s = string_view(s, size)
return result
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